mirror of
https://github.com/MariaDB/server.git
synced 2026-05-03 05:35:31 +02:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-maint
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.1-maint
This commit is contained in:
commit
c940d64a69
66 changed files with 6340 additions and 6243 deletions
|
|
@ -14,7 +14,12 @@
|
|||
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 "mysys_err.h"
|
||||
|
|
@ -23,20 +28,17 @@ static bool read_texts(const char *file_name,const char ***point,
|
|||
uint error_messages);
|
||||
static void init_myfunc_errs(void);
|
||||
|
||||
/*
|
||||
/**
|
||||
Read messages from errorfile.
|
||||
|
||||
SYNOPSIS
|
||||
init_errmessage()
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
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,
|
||||
uint error_messages)
|
||||
|
|
@ -178,7 +187,9 @@ err1:
|
|||
} /* read_texts */
|
||||
|
||||
|
||||
/* Initiates error-messages used by my_func-library */
|
||||
/**
|
||||
Initiates error-messages used by my_func-library.
|
||||
*/
|
||||
|
||||
static void init_myfunc_errs()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,17 +21,18 @@
|
|||
struct st_des_keyschedule des_keyschedule[10];
|
||||
uint des_default_key;
|
||||
|
||||
/*
|
||||
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 ;)
|
||||
#define des_cs &my_charset_latin1
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Error
|
||||
/**
|
||||
Load DES keys from plaintext file into
|
||||
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
|
||||
load_des_key_file(const char *file_name)
|
||||
|
|
|
|||
|
|
@ -14,29 +14,33 @@
|
|||
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 <my_dir.h>
|
||||
|
||||
/*
|
||||
Read the contents of a .frm file
|
||||
/**
|
||||
Read the contents of a .frm file.
|
||||
|
||||
SYNOPSIS
|
||||
readfrm()
|
||||
frmdata and len are set to 0 on error.
|
||||
|
||||
name path to table-file "db/name"
|
||||
frmdata frm data
|
||||
len length of the read frmdata
|
||||
@param name path to table-file "db/name"
|
||||
@param frmdata frm data
|
||||
@param len length of the read frmdata
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
1 Could not open file
|
||||
2 Could not stat file
|
||||
3 Could not allocate data for read
|
||||
Could not read file
|
||||
|
||||
frmdata and len are set to 0 on error
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 Could not open file
|
||||
@retval
|
||||
2 Could not stat file
|
||||
@retval
|
||||
3 Could not allocate data for read. Could not read file
|
||||
*/
|
||||
|
||||
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
|
||||
to a frm file
|
||||
to a frm file.
|
||||
|
||||
SYNOPSIS
|
||||
writefrm()
|
||||
@param name path to table-file "db/name"
|
||||
@param frmdata frm data
|
||||
@param len length of the frmdata
|
||||
|
||||
name path to table-file "db/name"
|
||||
frmdata frm data
|
||||
len length of the frmdata
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
2 Could not write file
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
2 Could not write file
|
||||
*/
|
||||
|
||||
int writefrm(const char *name, const uchar *frmdata, size_t len)
|
||||
|
|
|
|||
513
sql/field.cc
513
sql/field.cc
|
|
@ -14,9 +14,12 @@
|
|||
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
|
||||
#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
|
||||
Field::field_type_merge()
|
||||
a, b types for merging
|
||||
@param a type for merging
|
||||
@param b type for merging
|
||||
|
||||
RETURN
|
||||
@return
|
||||
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
|
||||
Field::result_merge_type()
|
||||
field_type given field type
|
||||
@param field_type given field type
|
||||
|
||||
RETURN
|
||||
@return
|
||||
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
|
||||
to check the type of a non-Field in mysql_alter_table().
|
||||
|
||||
SYNOPSIS
|
||||
type_can_have_key_part()
|
||||
type field type
|
||||
@param type field type
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE Type can have a prefixed key
|
||||
@retval
|
||||
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,
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
Field_num::check_int
|
||||
cs Character set
|
||||
str String to test
|
||||
end Pointer to char after last used digit
|
||||
length String length
|
||||
error Error returned by strntoull10rnd()
|
||||
@todo
|
||||
Make this multi-byte-character safe
|
||||
|
||||
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.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
1 error: empty string or wrong integer.
|
||||
@retval
|
||||
2 error: garbage at the end of string.
|
||||
*/
|
||||
|
||||
|
|
@ -1191,16 +1192,15 @@ out_of_range:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Process decimal library return codes and issue warnings for overflow and
|
||||
truncation.
|
||||
|
||||
SYNOPSIS
|
||||
Field::warn_if_overflow()
|
||||
op_result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
@param op_result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
1 there was overflow
|
||||
@retval
|
||||
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
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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)
|
||||
|
|
@ -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,
|
||||
uchar null_bit_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
|
||||
setting correct value (min/max) in case of overflow
|
||||
setting correct value (min/max) in case of overflow.
|
||||
|
||||
SYNOPSIS
|
||||
Field::convert_decimal2longlong()
|
||||
val value which have to be converted
|
||||
unsigned_flag type of integer in which we convert val
|
||||
err variable to pass error code
|
||||
@param val value which have to be converted
|
||||
@param unsigned_flag type of integer in which we convert val
|
||||
@param err variable to pass error code
|
||||
|
||||
RETURN
|
||||
@return
|
||||
value converted from 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.
|
||||
|
||||
SYNOPSIS
|
||||
Field_num::store_decimal()
|
||||
val value for storing
|
||||
@param val value for storing
|
||||
|
||||
NOTE
|
||||
@note
|
||||
This method is used by all integer fields, real/decimal redefine it
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 error
|
||||
@retval
|
||||
!=0 error
|
||||
*/
|
||||
|
||||
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
|
||||
Field_num::val_decimal()
|
||||
decimal_value buffer for storing decimal value
|
||||
@param decimal_value buffer for storing decimal value
|
||||
|
||||
NOTE
|
||||
This method is used by all integer fields, real/decimal redefine it
|
||||
@note
|
||||
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
|
||||
digits of integer number
|
||||
|
||||
RETURN
|
||||
@return
|
||||
pointer to decimal buffer with value of field
|
||||
*/
|
||||
|
||||
|
|
@ -1660,22 +1656,24 @@ void Field_num::make_field(Send_field *field)
|
|||
field->decimals= dec;
|
||||
}
|
||||
|
||||
/*
|
||||
Decimal representation of Field_str
|
||||
/**
|
||||
Decimal representation of Field_str.
|
||||
|
||||
SYNOPSIS
|
||||
Field_str::store_decimal()
|
||||
d value for storing
|
||||
@param d value for storing
|
||||
|
||||
NOTE
|
||||
Field_str is the base class for fields like Field_enum, Field_date and some
|
||||
similar. Some dates use fraction and also string value should be
|
||||
converted to floating point value according our rules, so we use double
|
||||
to store value of decimal in string
|
||||
@note
|
||||
Field_str is the base class for fields like Field_enum,
|
||||
Field_date and some similar. Some dates use fraction and also
|
||||
string value should be converted to floating point value according
|
||||
our rules, so we use double to store value of decimal in string.
|
||||
|
||||
RETURN
|
||||
@todo
|
||||
use decimal2string?
|
||||
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 error
|
||||
@retval
|
||||
!=0 error
|
||||
*/
|
||||
|
||||
int Field_str::store_decimal(const my_decimal *d)
|
||||
|
|
@ -1748,11 +1746,11 @@ bool Field::get_time(MYSQL_TIME *ltime)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
This is called when storing a date in a string
|
||||
/**
|
||||
This is called when storing a date in a string.
|
||||
|
||||
NOTES
|
||||
Needs to be changed if/when we want to support different time formats
|
||||
@note
|
||||
Needs to be changed if/when we want to support different time formats.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
** Should be able to handle at least the following fixed decimal formats:
|
||||
** 5.00 , -1.0, 05, -05, +5 with optional pre/end space
|
||||
/**
|
||||
Should be able to handle at least the following fixed decimal formats:
|
||||
5.00 , -1.0, 05, -05, +5 with optional pre/end space
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
Field_new_decimal::set_value_on_overflow();
|
||||
decimal_value buffer for value
|
||||
sign sign of value which caused overflow
|
||||
@param decimal_value buffer for value
|
||||
@param sign sign of value which caused overflow
|
||||
*/
|
||||
|
||||
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
|
||||
store_value(const my_decimal *decimal_value)
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
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.
|
||||
@param decimal_value my_decimal
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
||||
|
|
@ -4667,9 +4667,8 @@ void Field_double::sql_type(String &res) const
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
TIMESTAMP type.
|
||||
Holds datetime values in range from 1970-01-01 00:00:01 UTC to
|
||||
/**
|
||||
TIMESTAMP type 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
|
||||
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()
|
||||
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
|
||||
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
|
||||
|
|
@ -4748,15 +4747,11 @@ Field_timestamp::Field_timestamp(bool maybe_null_arg,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Get auto-set type for TIMESTAMP field.
|
||||
|
||||
SYNOPSIS
|
||||
get_auto_set_type()
|
||||
|
||||
DESCRIPTION
|
||||
Returns value indicating during which operations this TIMESTAMP field
|
||||
should be auto-set to current timestamp.
|
||||
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
|
||||
{
|
||||
|
|
@ -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
|
||||
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
|
||||
get_date() here to be able to do things like
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
store(double nr)
|
||||
nr number
|
||||
Pretty prints double number into field_length characters buffer.
|
||||
|
||||
DESCRIPTION
|
||||
Pretty prints double number into field_length characters buffer.
|
||||
@param nr number
|
||||
*/
|
||||
|
||||
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
|
||||
pack_cmp()
|
||||
key Original key
|
||||
length Key length. (May be less than field length)
|
||||
insert_or_update 1 if this is an insert or update
|
||||
@param key Original key
|
||||
@param length Key length. (May be less than field length)
|
||||
@param insert_or_update 1 if this is an insert or update
|
||||
|
||||
RETURN
|
||||
@return
|
||||
< 0 row < key
|
||||
@return
|
||||
0 row = key
|
||||
@return
|
||||
> 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)
|
||||
|
|
@ -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().
|
||||
(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.
|
||||
|
||||
SYNOPSIS
|
||||
unpack_key()
|
||||
to Pointer into the record buffer.
|
||||
key Pointer to the packed key.
|
||||
max_length Key length limit from key description.
|
||||
A VARCHAR 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'.
|
||||
|
||||
DESCRIPTION
|
||||
A VARCHAR 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'.
|
||||
@param to Pointer into the record buffer.
|
||||
@param key Pointer to the packed key.
|
||||
@param max_length Key length limit from key description.
|
||||
|
||||
RETURN
|
||||
@return
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
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
|
||||
pack_key_from_key_image()
|
||||
to Store packed key segment here
|
||||
from Key segment (as given to index_read())
|
||||
max_length Max length of key
|
||||
@param to Store packed key segment here
|
||||
@param from Key segment (as given to index_read())
|
||||
@param max_length Max length of key
|
||||
|
||||
RETURN
|
||||
@return
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
Field_blob::put_length()
|
||||
pos Pointer into the record buffer.
|
||||
length The length value to put.
|
||||
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'.
|
||||
|
||||
DESCRIPTION
|
||||
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'.
|
||||
|
||||
RETURN
|
||||
nothing
|
||||
@param pos Pointer into the record buffer.
|
||||
@param length The length value to put.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 *
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
Field_blob::unpack_key()
|
||||
to Pointer into the record buffer.
|
||||
from Pointer to the packed key.
|
||||
max_length Key length limit from key 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.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
@ -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 *
|
||||
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
|
||||
** (if there isn't a empty value in the enum)
|
||||
/**
|
||||
@note
|
||||
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)
|
||||
|
|
@ -8686,7 +8669,12 @@ void Field_set::sql_type(String &res) const
|
|||
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)
|
||||
{
|
||||
|
|
@ -8696,6 +8684,10 @@ bool Field::eq_def(Field *field)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@return
|
||||
returns 1 if the fields are equally defined
|
||||
*/
|
||||
bool Field_enum::eq_def(Field *field)
|
||||
{
|
||||
if (!Field::eq_def(field))
|
||||
|
|
@ -8714,6 +8706,10 @@ bool Field_enum::eq_def(Field *field)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@return
|
||||
returns 1 if the fields are equally defined
|
||||
*/
|
||||
bool Field_num::eq_def(Field *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
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
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.
|
||||
/**
|
||||
Convert create_field::length from number of characters to number of bytes.
|
||||
*/
|
||||
|
||||
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,
|
||||
uint32 length_arg, uint32 decimals_arg,
|
||||
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
|
||||
thd Thread handle
|
||||
fld_name Field name
|
||||
fld_type Field type
|
||||
fld_length Field length
|
||||
fld_decimals Decimal (if any)
|
||||
fld_type_modifier Additional type information
|
||||
fld_default_value Field default value (if any)
|
||||
fld_on_update_value The value of ON UPDATE clause
|
||||
fld_comment Field comment
|
||||
fld_change Field change
|
||||
fld_interval_list Interval list (if any)
|
||||
fld_charset Field charset
|
||||
fld_geom_type Field geometry type (if any)
|
||||
@param thd Thread handle
|
||||
@param fld_name Field name
|
||||
@param fld_type Field type
|
||||
@param fld_length Field length
|
||||
@param fld_decimals Decimal (if any)
|
||||
@param fld_type_modifier Additional type information
|
||||
@param fld_default_value Field default value (if any)
|
||||
@param fld_on_update_value The value of ON UPDATE clause
|
||||
@param fld_comment Field comment
|
||||
@param fld_change Field change
|
||||
@param fld_interval_list Interval list (if any)
|
||||
@param fld_charset Field charset
|
||||
@param fld_geom_type Field geometry type (if any)
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
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)
|
||||
{
|
||||
|
|
@ -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
|
||||
Field_blob::max_display_length()
|
||||
|
||||
RETURN
|
||||
@return
|
||||
length
|
||||
*/
|
||||
|
||||
|
|
@ -10092,24 +10082,23 @@ uint32 Field_blob::max_display_length()
|
|||
Warning handling
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Produce warning or note about data saved into field
|
||||
/**
|
||||
Produce warning or note about data saved into field.
|
||||
|
||||
SYNOPSIS
|
||||
set_warning()
|
||||
level - level of message (Note/Warning/Error)
|
||||
code - error code of message to be produced
|
||||
cuted_increment - whenever we should increase cut fields count or not
|
||||
@param level - level of message (Note/Warning/Error)
|
||||
@param code - error code of message to be produced
|
||||
@param cuted_increment - whenever we should increase cut fields count or not
|
||||
|
||||
NOTE
|
||||
@note
|
||||
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 then we ignore notes.
|
||||
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
|
||||
@retval
|
||||
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
|
||||
set_datime_warning()
|
||||
level - level of message (Note/Warning/Error)
|
||||
code - error code of message to be produced
|
||||
str - string value which we tried to save
|
||||
str_len - length of string which we tried to save
|
||||
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
|
||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||
@param level level of message (Note/Warning/Error)
|
||||
@param code error code of message to be produced
|
||||
@param str string value which we tried to save
|
||||
@param str_length length of string which we tried to save
|
||||
@param ts_type type of datetime value (datetime/date/time)
|
||||
@param cuted_increment whenever we should increase cut fields count or not
|
||||
|
||||
@note
|
||||
This function will always produce some warning but won't increase cut
|
||||
fields counter if count_cuted_fields ==FIELD_CHECK_IGNORE for current
|
||||
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
|
||||
set_warning()
|
||||
level - level of message (Note/Warning/Error)
|
||||
code - error code of message to be produced
|
||||
nr - numeric value which we tried to save
|
||||
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
|
||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||
@param level level of message (Note/Warning/Error)
|
||||
@param code error code of message to be produced
|
||||
@param nr numeric value which we tried to save
|
||||
@param ts_type type of datetime value (datetime/date/time)
|
||||
@param cuted_increment whenever we should increase cut fields count or not
|
||||
|
||||
@note
|
||||
This function will always produce some warning but won't increase cut
|
||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||
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
|
||||
set_warning()
|
||||
level - level of message (Note/Warning/Error)
|
||||
code - error code of message to be produced
|
||||
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
|
||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||
@param level level of message (Note/Warning/Error)
|
||||
@param code error code of message to be produced
|
||||
@param nr double value which we tried to save
|
||||
@param ts_type type of datetime value (datetime/date/time)
|
||||
|
||||
@note
|
||||
This function will always produce some warning but won't increase cut
|
||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||
thread.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -14,11 +14,15 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
Functions to copy data to or from fields
|
||||
This could be done with a single short function but opencoding this
|
||||
gives much more speed.
|
||||
*/
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Functions to copy data to or from fields
|
||||
|
||||
This could be done with a single short function but opencoding this
|
||||
gives much more speed.
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include <m_ctype.h>
|
||||
|
|
@ -129,22 +133,21 @@ set_field_to_null(Field *field)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Set field to NULL or TIMESTAMP or to next auto_increment number
|
||||
/**
|
||||
Set field to NULL or TIMESTAMP or to next auto_increment number.
|
||||
|
||||
SYNOPSIS
|
||||
set_field_to_null_with_conversions()
|
||||
field Field to update
|
||||
no_conversion Set to 1 if we should return 1 if field can't
|
||||
take null values.
|
||||
If set to 0 we will do store the 'default value'
|
||||
if the field is a special field. If not we will
|
||||
give an error.
|
||||
@param field Field to update
|
||||
@param no_conversions Set to 1 if we should return 1 if field can't
|
||||
take null values.
|
||||
If set to 0 we will do store the 'default value'
|
||||
if the field is a special field. If not we will
|
||||
give an error.
|
||||
|
||||
RETURN VALUES
|
||||
0 Field could take 0 or an automatic conversion was used
|
||||
-1 Field could not take NULL and no conversion was used.
|
||||
If no_conversion was not set, an error message is printed
|
||||
@retval
|
||||
0 Field could take 0 or an automatic conversion was used
|
||||
@retval
|
||||
-1 Field could not take NULL and no conversion was used.
|
||||
If no_conversion was not set, an error message is printed
|
||||
*/
|
||||
|
||||
int
|
||||
|
|
@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy)
|
|||
copy->tmp.charset());
|
||||
}
|
||||
|
||||
/* Save blob in copy->tmp for GROUP BY */
|
||||
/** Save blob in copy->tmp for GROUP BY. */
|
||||
|
||||
static void do_save_blob(Copy_field *copy)
|
||||
{
|
||||
|
|
@ -352,9 +355,9 @@ static void do_field_decimal(Copy_field *copy)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
string copy for single byte characters set when to string is shorter than
|
||||
from string
|
||||
from string.
|
||||
*/
|
||||
|
||||
static void do_cut_string(Copy_field *copy)
|
||||
|
|
@ -374,9 +377,9 @@ static void do_cut_string(Copy_field *copy)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
string copy for multi byte characters set when to string is shorter than
|
||||
from string
|
||||
from string.
|
||||
*/
|
||||
|
||||
static void do_cut_string_complex(Copy_field *copy)
|
||||
|
|
@ -507,7 +510,7 @@ static void do_varstring2_mb(Copy_field *copy)
|
|||
** The different functions that fills in a Copy_field class
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
copy of field to maybe null string.
|
||||
If field is null then the all bytes are set to 0.
|
||||
if field is not null then the first byte is set to 1 and the rest of the
|
||||
|
|
@ -748,7 +751,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
|
|||
}
|
||||
|
||||
|
||||
/* Simple quick field convert that is called on insert */
|
||||
/** Simple quick field convert that is called on insert. */
|
||||
|
||||
int field_conv(Field *to,Field *from)
|
||||
{
|
||||
|
|
|
|||
296
sql/filesort.cc
296
sql/filesort.cc
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Sorts a database */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Sorts a database
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#ifdef HAVE_STDDEF_H
|
||||
|
|
@ -27,8 +32,7 @@
|
|||
#define SKIP_DBUG_IN_FILESORT
|
||||
#endif
|
||||
|
||||
/* How to write record_ref. */
|
||||
|
||||
/// How to write record_ref.
|
||||
#define WRITE_REF(file,from) \
|
||||
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
||||
DBUG_RETURN(1);
|
||||
|
|
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
|
|||
uint sortlength, uint *plength);
|
||||
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
||||
uchar *buff);
|
||||
/**
|
||||
Sort a table.
|
||||
Creates a set of pointers that can be used to read the rows
|
||||
in sorted order. This should be done with the functions
|
||||
in records.cc.
|
||||
|
||||
/*
|
||||
Sort a table
|
||||
Before calling filesort, one must have done
|
||||
table->file->info(HA_STATUS_VARIABLE)
|
||||
|
||||
SYNOPSIS
|
||||
filesort()
|
||||
table Table to sort
|
||||
sortorder How to sort the table
|
||||
s_length Number of elements in sortorder
|
||||
select Condition to apply to the rows
|
||||
ha_maxrows Return only this many rows
|
||||
sort_positions Set to 1 if we want to force sorting by position
|
||||
The result set is stored in table->io_cache or
|
||||
table->record_pointers.
|
||||
|
||||
@param thd Current thread
|
||||
@param table Table to sort
|
||||
@param sortorder How to sort the table
|
||||
@param s_length Number of elements in sortorder
|
||||
@param select condition to apply to the rows
|
||||
@param max_rows Return only this many rows
|
||||
@param sort_positions Set to 1 if we want to force sorting by position
|
||||
(Needed by UPDATE/INSERT or ALTER TABLE)
|
||||
examined_rows Store number of examined rows here
|
||||
@param examined_rows Store number of examined rows here
|
||||
|
||||
IMPLEMENTATION
|
||||
Creates a set of pointers that can be used to read the rows
|
||||
in sorted order. This should be done with the functions
|
||||
in records.cc
|
||||
|
||||
REQUIREMENTS
|
||||
Before calling filesort, one must have done
|
||||
table->file->info(HA_STATUS_VARIABLE)
|
||||
|
||||
NOTES
|
||||
@todo
|
||||
check why we do this (param.keys--)
|
||||
@note
|
||||
If we sort by position (like if sort_positions is 1) filesort() will
|
||||
call table->prepare_for_position().
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
HA_POS_ERROR Error
|
||||
# Number of rows
|
||||
|
||||
@retval
|
||||
\# Number of rows
|
||||
@retval
|
||||
examined_rows will be set to number of examined rows
|
||||
|
||||
The result set is stored in table->io_cache or
|
||||
table->record_pointers
|
||||
*/
|
||||
|
||||
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||
|
|
@ -351,7 +353,7 @@ void filesort_free_buffers(TABLE *table, bool full)
|
|||
}
|
||||
}
|
||||
|
||||
/* Make a array of string pointers */
|
||||
/** Make a array of string pointers. */
|
||||
|
||||
static char **make_char_array(char **old_pos, register uint fields,
|
||||
uint length, myf my_flag)
|
||||
|
|
@ -372,7 +374,7 @@ static char **make_char_array(char **old_pos, register uint fields,
|
|||
} /* make_char_array */
|
||||
|
||||
|
||||
/* Read 'count' number of buffer pointers into memory */
|
||||
/** Read 'count' number of buffer pointers into memory. */
|
||||
|
||||
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||
{
|
||||
|
|
@ -395,38 +397,40 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Search after sort_keys and write them into tempfile.
|
||||
SYNOPSIS
|
||||
find_all_keys()
|
||||
param Sorting parameter
|
||||
select Use this to get source data
|
||||
sort_keys Array of pointers to sort key + addon buffers.
|
||||
buffpek_pointers File to write BUFFPEKs describing sorted segments
|
||||
in tempfile.
|
||||
tempfile File to write sorted sequences of sortkeys to.
|
||||
indexfile If !NULL, use it for source data (contains rowids)
|
||||
|
||||
NOTE
|
||||
All produced sequences are guaranteed to be non-empty.
|
||||
|
||||
@param param Sorting parameter
|
||||
@param select Use this to get source data
|
||||
@param sort_keys Array of pointers to sort key + addon buffers.
|
||||
@param buffpek_pointers File to write BUFFPEKs describing sorted segments
|
||||
in tempfile.
|
||||
@param tempfile File to write sorted sequences of sortkeys to.
|
||||
@param indexfile If !NULL, use it for source data (contains rowids)
|
||||
|
||||
@note
|
||||
Basic idea:
|
||||
while (get_next_sortkey())
|
||||
{
|
||||
if (no free space in sort_keys buffers)
|
||||
{
|
||||
sort sort_keys buffer;
|
||||
dump sorted sequence to 'tempfile';
|
||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||
}
|
||||
put sort key into 'sort_keys';
|
||||
}
|
||||
if (sort_keys has some elements && dumped at least once)
|
||||
sort-dump-dump as above;
|
||||
else
|
||||
don't sort, leave sort_keys array to be sorted by caller.
|
||||
|
||||
All produced sequences are guaranteed to be non-empty.
|
||||
RETURN
|
||||
@verbatim
|
||||
while (get_next_sortkey())
|
||||
{
|
||||
if (no free space in sort_keys buffers)
|
||||
{
|
||||
sort sort_keys buffer;
|
||||
dump sorted sequence to 'tempfile';
|
||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||
}
|
||||
put sort key into 'sort_keys';
|
||||
}
|
||||
if (sort_keys has some elements && dumped at least once)
|
||||
sort-dump-dump as above;
|
||||
else
|
||||
don't sort, leave sort_keys array to be sorted by caller.
|
||||
@endverbatim
|
||||
|
||||
@retval
|
||||
Number of records written on success.
|
||||
@retval
|
||||
HA_POS_ERROR on error.
|
||||
*/
|
||||
|
||||
|
|
@ -594,23 +598,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
|||
} /* find_all_keys */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
Sort the buffer and write:
|
||||
1) the sorted sequence to tempfile
|
||||
2) a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||
(was: Skriver en buffert med nycklar till filen)
|
||||
SYNOPSIS
|
||||
write_keys()
|
||||
param Sort parameters
|
||||
sort_keys Array of pointers to keys to sort
|
||||
count Number of elements in sort_keys array
|
||||
buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||
The BUFFPEK::{file_pos, count} will indicate where
|
||||
the sorted data was stored.
|
||||
tempfile The sorted sequence will be written into this file.
|
||||
|
||||
RETURN
|
||||
-# the sorted sequence to tempfile
|
||||
-# a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||
|
||||
(was: Skriver en buffert med nycklar till filen)
|
||||
|
||||
@param param Sort parameters
|
||||
@param sort_keys Array of pointers to keys to sort
|
||||
@param count Number of elements in sort_keys array
|
||||
@param buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||
The BUFFPEK::{file_pos, count} will indicate where
|
||||
the sorted data was stored.
|
||||
@param tempfile The sorted sequence will be written into this file.
|
||||
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
|
|
@ -653,8 +659,8 @@ err:
|
|||
} /* write_keys */
|
||||
|
||||
|
||||
/*
|
||||
Store length as suffix in high-byte-first order
|
||||
/**
|
||||
Store length as suffix in high-byte-first order.
|
||||
*/
|
||||
|
||||
static inline void store_length(uchar *to, uint length, uint pack_length)
|
||||
|
|
@ -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,
|
||||
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,
|
||||
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
||||
|
|
@ -1043,8 +1049,12 @@ cleanup:
|
|||
} /* merge_many_buff */
|
||||
|
||||
|
||||
/* Read data to buffer */
|
||||
/* This returns (uint) -1 if something goes wrong */
|
||||
/**
|
||||
Read data to buffer.
|
||||
|
||||
@retval
|
||||
(uint)-1 if something goes wrong
|
||||
*/
|
||||
|
||||
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
||||
uint rec_length)
|
||||
|
|
@ -1066,15 +1076,15 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
|||
} /* read_to_buffer */
|
||||
|
||||
|
||||
/*
|
||||
Put all room used by freed buffer to use in adjacent buffer. Note, that
|
||||
we can't simply distribute memory evenly between all buffers, because
|
||||
new areas must not overlap with old ones.
|
||||
SYNOPSIS
|
||||
reuse_freed_buff()
|
||||
queue IN list of non-empty buffers, without freed buffer
|
||||
reuse IN empty buffer
|
||||
key_length IN key length
|
||||
/**
|
||||
Put all room used by freed buffer to use in adjacent buffer.
|
||||
|
||||
Note, that we can't simply distribute memory evenly between all buffers,
|
||||
because new areas must not overlap with old ones.
|
||||
|
||||
@param[in] queue list of non-empty buffers, without freed buffer
|
||||
@param[in] reuse empty buffer
|
||||
@param[in] key_length key length
|
||||
*/
|
||||
|
||||
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
||||
|
|
@ -1099,22 +1109,22 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Merge buffers to one buffer
|
||||
SYNOPSIS
|
||||
merge_buffers()
|
||||
param Sort parameter
|
||||
from_file File with source data (BUFFPEKs point to this file)
|
||||
to_file File to write the sorted result data.
|
||||
sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
||||
lastbuff OUT Store here BUFFPEK describing data written to to_file
|
||||
Fb First element in source BUFFPEKs array
|
||||
Tb Last element in source BUFFPEKs array
|
||||
flag
|
||||
/**
|
||||
Merge buffers to one buffer.
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
other - error
|
||||
@param param Sort parameter
|
||||
@param from_file File with source data (BUFFPEKs point to this file)
|
||||
@param to_file File to write the sorted result data.
|
||||
@param sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
||||
@param lastbuff OUT Store here BUFFPEK describing data written to to_file
|
||||
@param Fb First element in source BUFFPEKs array
|
||||
@param Tb Last element in source BUFFPEKs array
|
||||
@param flag
|
||||
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
other error
|
||||
*/
|
||||
|
||||
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||
|
|
@ -1350,23 +1360,21 @@ static uint suffix_length(ulong string_length)
|
|||
|
||||
|
||||
|
||||
/*
|
||||
Calculate length of sort key
|
||||
/**
|
||||
Calculate length of sort key.
|
||||
|
||||
SYNOPSIS
|
||||
sortlength()
|
||||
thd Thread handler
|
||||
sortorder Order of items to sort
|
||||
uint s_length Number of items to sort
|
||||
multi_byte_charset (out)
|
||||
Set to 1 if we are using multi-byte charset
|
||||
(In which case we have to use strxnfrm())
|
||||
@param thd Thread handler
|
||||
@param sortorder Order of items to sort
|
||||
@param s_length Number of items to sort
|
||||
@param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
|
||||
(In which case we have to use strxnfrm())
|
||||
|
||||
NOTES
|
||||
sortorder->length is updated for each sort item
|
||||
@note
|
||||
sortorder->length is updated for each sort item.
|
||||
@n
|
||||
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
||||
|
||||
RETURN
|
||||
@return
|
||||
Total length of sort buffer in bytes
|
||||
*/
|
||||
|
||||
|
|
@ -1453,33 +1461,31 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Get descriptors of fields appended to sorted fields and
|
||||
calculate its total length
|
||||
calculate its total length.
|
||||
|
||||
SYNOPSIS
|
||||
get_addon_fields()
|
||||
thd Current thread
|
||||
ptabfields Array of references to the table fields
|
||||
sortlength Total length of sorted fields
|
||||
plength out: Total length of appended fields
|
||||
The function first finds out what fields are used in the result set.
|
||||
Then it calculates the length of the buffer to store the values of
|
||||
these fields together with the value of sort values.
|
||||
If the calculated length is not greater than max_length_for_sort_data
|
||||
the function allocates memory for an array of descriptors containing
|
||||
layouts for the values of the non-sorted fields in the buffer and
|
||||
fills them.
|
||||
|
||||
DESCRIPTION
|
||||
The function first finds out what fields are used in the result set.
|
||||
Then it calculates the length of the buffer to store the values of
|
||||
these fields together with the value of sort values.
|
||||
If the calculated length is not greater than max_length_for_sort_data
|
||||
the function allocates memory for an array of descriptors containing
|
||||
layouts for the values of the non-sorted fields in the buffer and
|
||||
fills them.
|
||||
@param thd Current thread
|
||||
@param ptabfield Array of references to the table fields
|
||||
@param sortlength Total length of sorted fields
|
||||
@param[out] plength Total length of appended fields
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The null bits for the appended values are supposed to be put together
|
||||
and stored the buffer just ahead of the value of the first field.
|
||||
|
||||
RETURN
|
||||
@return
|
||||
Pointer to the layout descriptors for the appended fields, if any
|
||||
NULL - if we do not store field values with sort data.
|
||||
@retval
|
||||
NULL if we do not store field values with sort data.
|
||||
*/
|
||||
|
||||
static SORT_ADDON_FIELD *
|
||||
|
|
@ -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.
|
||||
|
||||
SYNOPSIS
|
||||
unpack_addon_fields()
|
||||
addon_field Array of descriptors for appended fields
|
||||
buff Buffer which to unpack the value from
|
||||
@param addon_field Array of descriptors for appended fields
|
||||
@param buff Buffer which to unpack the value from
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The function is supposed to be used only as a callback function
|
||||
when getting field values for the sorted result set.
|
||||
|
||||
RETURN
|
||||
@return
|
||||
void.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
@details
|
||||
@verbatim
|
||||
The idea of presented algorithm see in
|
||||
"The Art of Computer Programming" by Donald E. Knuth
|
||||
Volume 3 "Sorting and searching"
|
||||
|
|
@ -63,12 +66,14 @@ for optimization, link is the 16-bit index in 'symbols' or 'sql_functions'
|
|||
or search-array..
|
||||
|
||||
So, we can read full search-structure as 32-bit word
|
||||
@endverbatim
|
||||
|
||||
@todo
|
||||
use instead to_upper_lex, special array
|
||||
(substitute chars) without skip codes..
|
||||
@todo
|
||||
try use reverse order of comparing..
|
||||
|
||||
TODO:
|
||||
1. use instead to_upper_lex, special array
|
||||
(substitute chars) without skip codes..
|
||||
2. try use reverse order of comparing..
|
||||
|
||||
*/
|
||||
|
||||
#define NO_YACC_SYMBOLS
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
465
sql/handler.cc
465
sql/handler.cc
|
|
@ -199,8 +199,8 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
Use other database handler if databasehandler is not compiled in
|
||||
/**
|
||||
Use other database handler if databasehandler is not compiled in.
|
||||
*/
|
||||
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
|
||||
bool no_substitute, bool report_error)
|
||||
|
|
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
|
|||
#endif
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Register handler error messages for use with my_error().
|
||||
|
||||
SYNOPSIS
|
||||
ha_init_errors()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 Error
|
||||
@retval
|
||||
!=0 Error
|
||||
*/
|
||||
static int ha_init_errors(void)
|
||||
{
|
||||
|
|
@ -349,15 +347,13 @@ static int ha_init_errors(void)
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Unregister handler error messages.
|
||||
|
||||
SYNOPSIS
|
||||
ha_finish_errors()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
!= 0 Error
|
||||
@retval
|
||||
!=0 Error
|
||||
*/
|
||||
static int ha_finish_errors(void)
|
||||
{
|
||||
|
|
@ -567,8 +563,9 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
don't bother to rollback here, it's done already
|
||||
/**
|
||||
@note
|
||||
don't bother to rollback here, it's done already
|
||||
*/
|
||||
void ha_close_connection(THD* thd)
|
||||
{
|
||||
|
|
@ -578,17 +575,16 @@ void ha_close_connection(THD* thd)
|
|||
/* ========================================================================
|
||||
======================= TRANSACTIONS ===================================*/
|
||||
|
||||
/** @brief
|
||||
Register a storage engine for a transaction
|
||||
/**
|
||||
Register a storage engine for a transaction.
|
||||
|
||||
DESCRIPTION
|
||||
Every storage engine MUST call this function when it starts
|
||||
a transaction or a statement (that is it must be called both for the
|
||||
"beginning of transaction" and "beginning of statement").
|
||||
Only storage engines registered for the transaction/statement
|
||||
will know when to commit/rollback it.
|
||||
Every storage engine MUST call this function when it starts
|
||||
a transaction or a statement (that is it must be called both for the
|
||||
"beginning of transaction" and "beginning of statement").
|
||||
Only storage engines registered for the transaction/statement
|
||||
will know when to commit/rollback it.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
trans_register_ha is idempotent - storage engine may register many
|
||||
times per transaction.
|
||||
|
||||
|
|
@ -620,10 +616,11 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - error, transaction was rolled back
|
||||
/**
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error, transaction was rolled back
|
||||
*/
|
||||
int ha_prepare(THD *thd)
|
||||
{
|
||||
|
|
@ -660,11 +657,19 @@ int ha_prepare(THD *thd)
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
RETURN
|
||||
0 - ok
|
||||
1 - transaction was rolled back
|
||||
2 - error during commit, data may be inconsistent
|
||||
/**
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 transaction was rolled back
|
||||
@retval
|
||||
2 error during commit, data may be inconsistent
|
||||
|
||||
@todo
|
||||
Since we don't support nested statement transactions in 5.0,
|
||||
we can't commit or rollback stmt transactions while we are inside
|
||||
stored functions or triggers. So we simply do nothing now.
|
||||
TODO: This should be fixed in later ( >= 5.1) releases.
|
||||
*/
|
||||
int ha_commit_trans(THD *thd, bool all)
|
||||
{
|
||||
|
|
@ -757,9 +762,9 @@ end:
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
NOTE - this function does not care about global read lock.
|
||||
A caller should.
|
||||
/**
|
||||
@note
|
||||
This function does not care about global read lock. A caller should.
|
||||
*/
|
||||
int ha_commit_one_phase(THD *thd, bool all)
|
||||
{
|
||||
|
|
@ -869,13 +874,16 @@ int ha_rollback_trans(THD *thd, bool all)
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
This is used to commit or rollback a single statement depending on the value
|
||||
of error. Note that if the autocommit is on, then the following call inside
|
||||
InnoDB will commit or rollback the whole transaction (= the statement). The
|
||||
autocommit mechanism built into InnoDB is based on counting locks, but if
|
||||
the user has used LOCK TABLES then that mechanism does not know to do the
|
||||
commit.
|
||||
/**
|
||||
This is used to commit or rollback a single statement depending on
|
||||
the value of error.
|
||||
|
||||
@note
|
||||
Note that if the autocommit is on, then the following call inside
|
||||
InnoDB will commit or rollback the whole transaction (= the statement). The
|
||||
autocommit mechanism built into InnoDB is based on counting locks, but if
|
||||
the user has used LOCK TABLES then that mechanism does not know to do the
|
||||
commit.
|
||||
*/
|
||||
int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
{
|
||||
|
|
@ -944,7 +952,10 @@ int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
|
|||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/* this does not need to be multi-byte safe or anything */
|
||||
/**
|
||||
@note
|
||||
This does not need to be multi-byte safe or anything
|
||||
*/
|
||||
static char* xid_to_str(char *buf, XID *xid)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -996,24 +1007,21 @@ static char* xid_to_str(char *buf, XID *xid)
|
|||
}
|
||||
#endif
|
||||
|
||||
/** @brief
|
||||
recover() step of xa
|
||||
/**
|
||||
recover() step of xa.
|
||||
|
||||
NOTE
|
||||
there are three modes of operation:
|
||||
|
||||
- automatic recover after a crash
|
||||
in this case commit_list != 0, tc_heuristic_recover==0
|
||||
all xids from commit_list are committed, others are rolled back
|
||||
|
||||
- manual (heuristic) recover
|
||||
in this case commit_list==0, tc_heuristic_recover != 0
|
||||
DBA has explicitly specified that all prepared transactions should
|
||||
be committed (or rolled back).
|
||||
|
||||
- no recovery (MySQL did not detect a crash)
|
||||
in this case commit_list==0, tc_heuristic_recover == 0
|
||||
there should be no prepared transactions in this case.
|
||||
@note
|
||||
there are three modes of operation:
|
||||
- automatic recover after a crash
|
||||
in this case commit_list != 0, tc_heuristic_recover==0
|
||||
all xids from commit_list are committed, others are rolled back
|
||||
- manual (heuristic) recover
|
||||
in this case commit_list==0, tc_heuristic_recover != 0
|
||||
DBA has explicitly specified that all prepared transactions should
|
||||
be committed (or rolled back).
|
||||
- no recovery (MySQL did not detect a crash)
|
||||
in this case commit_list==0, tc_heuristic_recover == 0
|
||||
there should be no prepared transactions in this case.
|
||||
*/
|
||||
struct xarecover_st
|
||||
{
|
||||
|
|
@ -1146,10 +1154,10 @@ int ha_recover(HASH *commit_list)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
return the list of XID's to a client, the same way SHOW commands do
|
||||
/**
|
||||
return the list of XID's to a client, the same way SHOW commands do.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
I didn't find in XA specs that an RM cannot return the same XID twice,
|
||||
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
||||
It can be easily fixed later, if necessary.
|
||||
|
|
@ -1195,7 +1203,8 @@ bool mysql_xa_recover(THD *thd)
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
@details
|
||||
This function should be called when MySQL sends rows of a SELECT result set
|
||||
or the EOF mark to the client. It releases a possible adaptive hash index
|
||||
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
||||
|
|
@ -1207,9 +1216,10 @@ bool mysql_xa_recover(THD *thd)
|
|||
performs another SQL query. In MySQL-4.1 this is even more important because
|
||||
there a connection can have several SELECT queries open at the same time.
|
||||
|
||||
arguments:
|
||||
thd: the thread handle of the current connection
|
||||
return value: always 0
|
||||
@param thd the thread handle of the current connection
|
||||
|
||||
@return
|
||||
always 0
|
||||
*/
|
||||
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
||||
void *unused)
|
||||
|
|
@ -1276,8 +1286,9 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
note, that according to the sql standard (ISO/IEC 9075-2:2003)
|
||||
/**
|
||||
@note
|
||||
according to the sql standard (ISO/IEC 9075-2:2003)
|
||||
section "4.33.4 SQL-statements and transaction states",
|
||||
SAVEPOINT is *not* transaction-initiating SQL-statement
|
||||
*/
|
||||
|
|
@ -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
|
||||
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);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Generate the next auto-increment number based on increment and offset:
|
||||
/**
|
||||
Generate the next auto-increment number based on increment and offset.
|
||||
computes the lowest number
|
||||
- strictly greater than "nr"
|
||||
- of the form: auto_increment_offset + N * auto_increment_increment
|
||||
|
||||
In most cases increment= offset= 1, in which case we get:
|
||||
1,2,3,4,5,...
|
||||
If increment=10 and offset=5 and previous number is 1, we get:
|
||||
1,5,15,25,35,...
|
||||
@verbatim 1,2,3,4,5,... @endverbatim
|
||||
If increment=10 and offset=5 and previous number is 1, we get:
|
||||
@verbatim 1,5,15,25,35,... @endverbatim
|
||||
*/
|
||||
inline ulonglong
|
||||
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
|
||||
|
|
@ -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
|
||||
update_auto_increment()
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
HA_ERR_AUTOINC_READ_FAILED
|
||||
get_auto_increment() was called and returned ~(ulonglong) 0
|
||||
HA_ERR_AUTOINC_ERANGE
|
||||
storing value in field caused strict mode failure.
|
||||
|
||||
|
||||
IMPLEMENTATION
|
||||
|
||||
Updates the record's Field of type NEXT_NUMBER if:
|
||||
Updates columns with type NEXT_NUMBER if:
|
||||
|
||||
- If column value is set to NULL (in which case
|
||||
auto_increment_field_not_null is 0)
|
||||
|
|
@ -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
|
||||
this list.
|
||||
|
||||
TODO
|
||||
|
||||
@todo
|
||||
Replace all references to "next number" or NEXT_NUMBER to
|
||||
"auto_increment", everywhere (see below: there is
|
||||
table->auto_increment_field_not_null, and there also exists
|
||||
table->next_number_field, it's not consistent).
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
HA_ERR_AUTOINC_READ_FAILED get_auto_increment() was called and
|
||||
returned ~(ulonglong) 0
|
||||
@retval
|
||||
HA_ERR_AUTOINC_ERANGE storing value in field caused strict mode
|
||||
failure.
|
||||
*/
|
||||
|
||||
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
|
||||
|
|
@ -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
|
||||
In case of delete table it's only safe to use the following parts of
|
||||
the 'table' structure:
|
||||
table->s->path
|
||||
table->alias
|
||||
@note
|
||||
In case of delete table it's only safe to use the following parts of
|
||||
the 'table' structure:
|
||||
- table->s->path
|
||||
- table->alias
|
||||
*/
|
||||
void handler::print_error(int error, myf errflag)
|
||||
{
|
||||
|
|
@ -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
|
||||
error error code previously returned by handler
|
||||
buf Pointer to String where to add error message
|
||||
@param error error code previously returned by handler
|
||||
@param buf pointer to String where to add error message
|
||||
|
||||
Returns true if this is a temporary error
|
||||
@return
|
||||
Returns true if this is a temporary error
|
||||
*/
|
||||
bool handler::get_error_message(int error, String* buf)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
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
|
||||
delete_table()
|
||||
name Base name of table
|
||||
@param name Base name of table
|
||||
|
||||
NOTES
|
||||
@note
|
||||
We assume that the handler may return more extensions than
|
||||
was actually used for the file.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 If we successfully deleted at least one file from base_ext and
|
||||
didn't get any other errors than ENOENT
|
||||
# Error
|
||||
didn't get any other errors than ENOENT
|
||||
@retval
|
||||
!0 Error
|
||||
*/
|
||||
int handler::delete_table(const char *name)
|
||||
{
|
||||
|
|
@ -2462,21 +2469,20 @@ void handler::drop_table(const char *name)
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
Performs checks upon the table.
|
||||
/**
|
||||
Performs checks upon the table.
|
||||
|
||||
SYNOPSIS
|
||||
check()
|
||||
thd thread doing CHECK TABLE operation
|
||||
check_opt options from the parser
|
||||
@param thd thread doing CHECK TABLE operation
|
||||
@param check_opt options from the parser
|
||||
|
||||
NOTES
|
||||
|
||||
RETURN
|
||||
HA_ADMIN_OK Successful upgrade
|
||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||
HA_ADMIN_NOT_IMPLEMENTED
|
||||
@retval
|
||||
HA_ADMIN_OK Successful upgrade
|
||||
@retval
|
||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||
@retval
|
||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||
@retval
|
||||
HA_ADMIN_NOT_IMPLEMENTED
|
||||
*/
|
||||
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
|
|
@ -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
|
||||
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.
|
||||
|
|
@ -2620,15 +2626,12 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
|||
** Some general functions that isn't in the handler class
|
||||
****************************************************************************/
|
||||
|
||||
/** @brief
|
||||
Initiates table-file and calls appropriate database-creator
|
||||
/**
|
||||
Initiates table-file and calls appropriate database-creator.
|
||||
|
||||
NOTES
|
||||
We must have a write lock on LOCK_open to be sure no other thread
|
||||
interferes with table
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
int ha_create_table(THD *thd, const char *path,
|
||||
|
|
@ -2666,17 +2669,18 @@ err:
|
|||
DBUG_RETURN(error != 0);
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Try to discover table from engine
|
||||
/**
|
||||
Try to discover table from engine.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If found, write the frm file to disk.
|
||||
|
||||
RETURN VALUES:
|
||||
@retval
|
||||
-1 Table did not exists
|
||||
@retval
|
||||
0 Table created ok
|
||||
@retval
|
||||
> 0 Error, table existed but could not be created
|
||||
|
||||
*/
|
||||
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
|
||||
{
|
||||
|
|
@ -2747,8 +2751,8 @@ void st_ha_check_opt::init()
|
|||
call to ha_init_key_cache() (probably out of memory)
|
||||
*****************************************************************************/
|
||||
|
||||
/** @brief
|
||||
Init a key cache if it has not been initied before
|
||||
/**
|
||||
Init a key cache if it has not been initied before.
|
||||
*/
|
||||
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -2794,7 +2798,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Change parameters for key cache (like size)
|
||||
*/
|
||||
int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
||||
|
|
@ -2810,8 +2814,8 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Free memory allocated by a key cache
|
||||
/**
|
||||
Free memory allocated by a key cache.
|
||||
*/
|
||||
int ha_end_key_cache(KEY_CACHE *key_cache)
|
||||
{
|
||||
|
|
@ -2819,8 +2823,8 @@ int ha_end_key_cache(KEY_CACHE *key_cache)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** @brief
|
||||
Move all tables from one key cache to another one
|
||||
/**
|
||||
Move all tables from one key cache to another one.
|
||||
*/
|
||||
int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
||||
KEY_CACHE *new_key_cache)
|
||||
|
|
@ -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
|
||||
-1 : Table did not exists
|
||||
0 : OK. In this case *frmblob and *frmlen are set
|
||||
>0 : error. frmblob and frmlen may not be set
|
||||
@retval
|
||||
-1 Table did not exists
|
||||
@retval
|
||||
0 OK. In this case *frmblob and *frmlen are set
|
||||
@retval
|
||||
>0 error. frmblob and frmlen may not be set
|
||||
*/
|
||||
struct st_discover_args
|
||||
{
|
||||
|
|
@ -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
|
||||
to ask engine if there are any new tables that should be written to disk
|
||||
/**
|
||||
Call this function in order to give the handler the possiblity
|
||||
to ask engine if there are any new tables that should be written to disk
|
||||
or any dropped tables that need to be removed from disk
|
||||
*/
|
||||
struct st_find_files_args
|
||||
|
|
@ -2926,16 +2932,15 @@ ha_find_files(THD *thd,const char *db,const char *path,
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Ask handler if the table exists in engine
|
||||
|
||||
RETURN
|
||||
/**
|
||||
Ask handler if the table exists in engine.
|
||||
@retval
|
||||
HA_ERR_NO_SUCH_TABLE Table does not exist
|
||||
@retval
|
||||
HA_ERR_TABLE_EXIST Table exists
|
||||
# Error code
|
||||
|
||||
*/
|
||||
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
struct st_table_exists_in_engine_args
|
||||
{
|
||||
const char *db;
|
||||
|
|
@ -3110,29 +3115,29 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
|
|||
}
|
||||
#endif
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Read the first row of a multi-range set.
|
||||
|
||||
SYNOPSIS
|
||||
read_multi_range_first()
|
||||
found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||
range_count Number of ranges in 'ranges'.
|
||||
sorted If result should be sorted per key.
|
||||
buffer A HANDLER_BUFFER for internal handler usage.
|
||||
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
@param ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||
@param range_count Number of ranges in 'ranges'.
|
||||
@param sorted If result should be sorted per key.
|
||||
@param buffer A HANDLER_BUFFER for internal handler usage.
|
||||
|
||||
NOTES
|
||||
Record is read into table->record[0].
|
||||
*found_range_p returns a valid value only if read_multi_range_first()
|
||||
@note
|
||||
- Record is read into table->record[0].
|
||||
- *found_range_p returns a valid value only if read_multi_range_first()
|
||||
returns 0.
|
||||
Sorting is done within each range. If you want an overall sort, enter
|
||||
- Sorting is done within each range. If you want an overall sort, enter
|
||||
'ranges' with sorted ranges.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK, found a row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||
KEY_MULTI_RANGE *ranges, uint range_count,
|
||||
|
|
@ -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.
|
||||
|
||||
SYNOPSIS
|
||||
read_multi_range_next()
|
||||
found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||
corresponds to the returned row.
|
||||
|
||||
NOTES
|
||||
Record is read into table->record[0].
|
||||
*found_range_p returns a valid value only if read_multi_range_next()
|
||||
@note
|
||||
- Record is read into table->record[0].
|
||||
- *found_range_p returns a valid value only if read_multi_range_next()
|
||||
returns 0.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK, found a row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No (more) rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
||||
{
|
||||
|
|
@ -3238,25 +3243,24 @@ scan_it_again:
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Read first row between two ranges.
|
||||
Store ranges for future calls to read_range_next
|
||||
Store ranges for future calls to read_range_next.
|
||||
|
||||
SYNOPSIS
|
||||
read_range_first()
|
||||
start_key Start key. Is 0 if no min range
|
||||
end_key End key. Is 0 if no max range
|
||||
eq_range_arg Set to 1 if start_key == end_key and the range endpoints
|
||||
will not change during query execution.
|
||||
sorted Set to 1 if result should be sorted per key
|
||||
@param start_key Start key. Is 0 if no min range
|
||||
@param end_key End key. Is 0 if no max range
|
||||
@param eq_range_arg Set to 1 if start_key == end_key
|
||||
@param sorted Set to 1 if result should be sorted per key
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Record is read into table->record[0]
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Found row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
int handler::read_range_first(const key_range *start_key,
|
||||
const key_range *end_key,
|
||||
|
|
@ -3292,19 +3296,18 @@ int handler::read_range_first(const key_range *start_key,
|
|||
}
|
||||
|
||||
|
||||
/** @brief
|
||||
/**
|
||||
Read next row between two ranges.
|
||||
|
||||
SYNOPSIS
|
||||
read_range_next()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Record is read into table->record[0]
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Found row
|
||||
@retval
|
||||
HA_ERR_END_OF_FILE No rows in range
|
||||
# Error code
|
||||
@retval
|
||||
\# Error code
|
||||
*/
|
||||
int handler::read_range_next()
|
||||
{
|
||||
|
|
@ -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
|
||||
compare_key
|
||||
range range to compare to row. May be 0 for no range
|
||||
|
||||
NOTES
|
||||
See key.cc::key_cmp() for details
|
||||
@param range range to compare to row. May be 0 for no range
|
||||
|
||||
RETURN
|
||||
@seealso
|
||||
key.cc::key_cmp()
|
||||
|
||||
@return
|
||||
The return value is SIGN(key_in_row - range_key):
|
||||
|
||||
0 Key is equal to range or 'range' == 0 (no range)
|
||||
-1 Key is less than range
|
||||
1 Key is larger than range
|
||||
- 0 : Key is equal to range or 'range' == 0 (no range)
|
||||
- -1 : Key is less than range
|
||||
- 1 : Key is larger than range
|
||||
*/
|
||||
int handler::compare_key(key_range *range)
|
||||
{
|
||||
|
|
@ -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.
|
||||
|
||||
SYNOPSIS
|
||||
ha_known_exts()
|
||||
|
||||
NOTES
|
||||
No mutexes, worst case race is a minor surplus memory allocation
|
||||
We have to recreate the extension map if mysqld is restarted (for example
|
||||
within libmysqld)
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
pointer pointer to TYPELIB structure
|
||||
*/
|
||||
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
||||
|
|
|
|||
|
|
@ -14,9 +14,14 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
Get hostname for an IP. Hostnames are checked with reverse name lookup and
|
||||
checked that they doesn't resemble an ip.
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Get hostname for an IP.
|
||||
|
||||
Hostnames are checked with reverse name lookup and
|
||||
checked that they doesn't resemble an ip.
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Init and dummy functions for interface with unireg */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Init and dummy functions for interface with unireg
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include <m_ctype.h>
|
||||
|
|
|
|||
998
sql/item.cc
998
sql/item.cc
File diff suppressed because it is too large
Load diff
|
|
@ -14,12 +14,17 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Buffers to save and compare item values */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Buffers to save and compare item values
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
|
||||
/*
|
||||
** Create right type of Cached_item for an item
|
||||
/**
|
||||
Create right type of Cached_item for an item.
|
||||
*/
|
||||
|
||||
Cached_item *new_Cached_item(THD *thd, Item *item)
|
||||
|
|
@ -45,9 +50,11 @@ Cached_item *new_Cached_item(THD *thd, Item *item)
|
|||
|
||||
Cached_item::~Cached_item() {}
|
||||
|
||||
/*
|
||||
** Compare with old value and replace value with new value
|
||||
** Return true if values have changed
|
||||
/**
|
||||
Compare with old value and replace value with new value.
|
||||
|
||||
@return
|
||||
Return true if values have changed
|
||||
*/
|
||||
|
||||
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* This file defines all compare functions */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
This file defines all compare functions
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
|
|
@ -104,7 +109,7 @@ static int cmp_row_type(Item* item1, Item* item2)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Aggregates result types from the array of items.
|
||||
|
||||
SYNOPSIS:
|
||||
|
|
@ -117,11 +122,13 @@ static int cmp_row_type(Item* item1, Item* item2)
|
|||
This function aggregates result types from the array of items. Found type
|
||||
supposed to be used later for comparison of values of these items.
|
||||
Aggregation itself is performed by the item_cmp_type() function.
|
||||
The function also checks compatibility of row signatures for the
|
||||
submitted items (see the spec for the cmp_row_type function).
|
||||
@param[out] type the aggregated type
|
||||
@param items array of items to aggregate the type from
|
||||
@param nitems number of items in the array
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 type incompatibility has been detected
|
||||
@retval
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
|
|
@ -286,10 +293,11 @@ void Item_func_not::print(String *str)
|
|||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
special NOT for ALL subquery
|
||||
/**
|
||||
special NOT for ALL subquery.
|
||||
*/
|
||||
|
||||
|
||||
longlong Item_func_not_all::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
|
@ -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
|
||||
(return TRUE if underlying subquery do not return rows) but if subquery
|
||||
returns some rows it return same value as argument (TRUE/FALSE).
|
||||
/**
|
||||
Special NOP (No OPeration) for ALL subquery. It is like
|
||||
Item_func_not_all.
|
||||
|
||||
@return
|
||||
(return TRUE if underlying subquery do not return rows) but if subquery
|
||||
returns some rows it return same value as argument (TRUE/FALSE).
|
||||
*/
|
||||
|
||||
longlong Item_func_nop_all::val_int()
|
||||
|
|
@ -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.
|
||||
On successful conversion the original item is substituted for the
|
||||
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
|
||||
are converted to bigints).
|
||||
|
||||
NOTES
|
||||
@param thd thread handle
|
||||
@param field item will be converted using the type of this field
|
||||
@param[in,out] item reference to the item to convert
|
||||
|
||||
@note
|
||||
This function is called only at prepare stage.
|
||||
As all derived tables are filled only after all derived tables
|
||||
are prepared we do not evaluate items with subselects here because
|
||||
they can contain derived tables and thus we may attempt to use a
|
||||
table that has not been populated yet.
|
||||
|
||||
RESULT VALUES
|
||||
0 Can't convert item
|
||||
1 Item was replaced with an integer version of the item
|
||||
@retval
|
||||
0 Can't convert item
|
||||
@retval
|
||||
1 Item was replaced with an integer version of the item
|
||||
*/
|
||||
|
||||
static bool convert_constant_item(THD *thd, Field *field, Item **item)
|
||||
|
|
@ -1058,13 +1067,15 @@ int Arg_comparator::compare_string()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare strings byte by byte. End spaces are also compared.
|
||||
|
||||
RETURN
|
||||
< 0 *a < *b
|
||||
0 *b == *b
|
||||
> 0 *a > *b
|
||||
@retval
|
||||
<0 *a < *b
|
||||
@retval
|
||||
0 *b == *b
|
||||
@retval
|
||||
>0 *a > *b
|
||||
*/
|
||||
|
||||
int Arg_comparator::compare_binary_string()
|
||||
|
|
@ -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()
|
||||
{
|
||||
String *res1,*res2;
|
||||
|
|
@ -1230,7 +1242,7 @@ int Arg_comparator::compare_int_signed()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare values as BIGINT UNSIGNED.
|
||||
*/
|
||||
|
||||
|
|
@ -1253,7 +1265,7 @@ int Arg_comparator::compare_int_unsigned()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare signed (*a) with unsigned (*B)
|
||||
*/
|
||||
|
||||
|
|
@ -1278,7 +1290,7 @@ int Arg_comparator::compare_int_signed_unsigned()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare unsigned (*a) with signed (*B)
|
||||
*/
|
||||
|
||||
|
|
@ -1314,7 +1326,7 @@ int Arg_comparator::compare_e_int()
|
|||
return test(val1 == val2);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
||||
*/
|
||||
int Arg_comparator::compare_e_int_diff_signedness()
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
@ -1757,21 +1769,18 @@ void Item_func_interval::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute Item_func_interval()
|
||||
/**
|
||||
Execute Item_func_interval().
|
||||
|
||||
SYNOPSIS
|
||||
Item_func_interval::val_int()
|
||||
@note
|
||||
If we are doing a decimal comparison, we are evaluating the first
|
||||
item twice.
|
||||
|
||||
NOTES
|
||||
If we are doing a decimal comparison, we are
|
||||
evaluating the first item twice.
|
||||
|
||||
RETURN
|
||||
-1 if null value,
|
||||
0 if lower than lowest
|
||||
1 - arg_count-1 if between args[n] and args[n+1]
|
||||
arg_count if higher than biggest argument
|
||||
@return
|
||||
- -1 if null value,
|
||||
- 0 if lower than lowest
|
||||
- 1 - arg_count-1 if between args[n] and args[n+1]
|
||||
- arg_count if higher than biggest argument
|
||||
*/
|
||||
|
||||
longlong Item_func_interval::val_int()
|
||||
|
|
@ -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
|
||||
various attributes of the item tree with Item_func_between as its root.
|
||||
The function saves in ref the pointer to the item or to a newly created
|
||||
item that is considered as a replacement for the original one.
|
||||
|
||||
NOTES
|
||||
@param thd reference to the global context of the query thread
|
||||
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||
item is to be assigned
|
||||
|
||||
@note
|
||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||
a predicate/function level. Then it's easy to show that:
|
||||
@verbatim
|
||||
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
|
||||
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 got error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
various attributes of the item tree with Item_func_if as its root.
|
||||
The function saves in ref the pointer to the item or to a newly created
|
||||
item that is considered as a replacement for the original one.
|
||||
|
||||
NOTES
|
||||
@param thd reference to the global context of the query thread
|
||||
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||
item is to be assigned
|
||||
|
||||
@note
|
||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||
a predicate/function level. Then it's easy to show that:
|
||||
@verbatim
|
||||
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
||||
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 got error
|
||||
*/
|
||||
|
||||
|
|
@ -2390,11 +2397,14 @@ Item_func_nullif::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
nullif () returns NULL if arguments are equal, else it returns the
|
||||
first argument.
|
||||
/**
|
||||
@note
|
||||
Note that we have to evaluate the first argument twice as the compare
|
||||
may have been done with a different type than return value
|
||||
@return
|
||||
NULL if arguments are equal
|
||||
@return
|
||||
the first argument if not equal
|
||||
*/
|
||||
|
||||
double
|
||||
|
|
@ -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
|
||||
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
|
||||
0, REAL_RESULT to bit 1, so on.
|
||||
|
||||
RETURN
|
||||
NULL - Nothing found and there is no ELSE expression defined
|
||||
item - Found item or ELSE item if defined and all comparisons are
|
||||
@retval
|
||||
NULL Nothing found and there is no ELSE expression defined
|
||||
@retval
|
||||
item Found item or ELSE item if defined and all comparisons are
|
||||
failed
|
||||
*/
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -2780,7 +2787,7 @@ void Item_func_case::cleanup()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
various attributes of the item tree with Item_func_in as its root.
|
||||
The function saves in ref the pointer to the item or to a newly created
|
||||
item that is considered as a replacement for the original one.
|
||||
|
||||
NOTES
|
||||
@param thd reference to the global context of the query thread
|
||||
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||
item is to be assigned
|
||||
|
||||
@note
|
||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||
a predicate/function level. Then it's easy to show that:
|
||||
@verbatim
|
||||
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
|
||||
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 got error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
|
||||
SYNOPSIS
|
||||
transform()
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
/**
|
||||
Transform an Item_cond object with a transformer callback function.
|
||||
|
||||
The function recursively applies the transform method to each
|
||||
member item of the condition list.
|
||||
member item of the condition list.
|
||||
If the call of the method for a member item returns a new item
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_cond object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
of the Item_cond object.
|
||||
|
||||
@param transformer the transformer callback function to be applied to
|
||||
the nodes of the tree of the object
|
||||
@param arg parameter to be passed to the transformer
|
||||
|
||||
@return
|
||||
Item returned as the result of transformation of the root node
|
||||
*/
|
||||
|
||||
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||
|
|
@ -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
|
||||
|
||||
SYNOPSIS
|
||||
compile()
|
||||
analyzer the analyzer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg_p in/out parameter to be passed to the analyzer
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg_t parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
/**
|
||||
Compile Item_cond object with a processor and a transformer
|
||||
callback functions.
|
||||
|
||||
First the function applies the analyzer to the root node of
|
||||
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
||||
the function recursively applies the compile method to member
|
||||
|
|
@ -3966,9 +3960,16 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
|||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_cond object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
|
||||
@param analyzer the analyzer callback function to be applied to the
|
||||
nodes of the tree of the object
|
||||
@param[in,out] arg_p parameter to be passed to the analyzer
|
||||
@param transformer the transformer callback function to be applied to the
|
||||
nodes of the tree of the object
|
||||
@param arg_t parameter to be passed to the transformer
|
||||
|
||||
@return
|
||||
Item returned as the result of transformation of the root node
|
||||
*/
|
||||
|
||||
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||
|
|
@ -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
|
||||
split_sum_func()
|
||||
thd Thread handler
|
||||
ref_pointer_array Pointer to array of reference fields
|
||||
fields All fields in select
|
||||
The split is done to get an unique item for each SUM function
|
||||
so that we can easily find and calculate them.
|
||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||
sql_select.cc)
|
||||
|
||||
NOTES
|
||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||
that have or refer (HAVING) to a SUM expression.
|
||||
@param thd Thread handler
|
||||
@param ref_pointer_array Pointer to array of reference fields
|
||||
@param fields All fields in select
|
||||
|
||||
The split is done to get an unique item for each SUM function
|
||||
so that we can easily find and calculate them.
|
||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||
sql_select.cc)
|
||||
@note
|
||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||
that have or refer (HAVING) to a SUM expression.
|
||||
*/
|
||||
|
||||
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
|
|
@ -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
|
||||
result is NULL or 0. This is set for:
|
||||
- WHERE clause
|
||||
- HAVING clause
|
||||
- IF(expression)
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 If all expressions are true
|
||||
@retval
|
||||
0 If all expressions are false or if we find a NULL expression and
|
||||
'abort_on_null' is set.
|
||||
'abort_on_null' is set.
|
||||
@retval
|
||||
NULL if all expression are either 1 or NULL
|
||||
*/
|
||||
|
||||
|
|
@ -4159,24 +4160,23 @@ longlong Item_cond_or::val_int()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Create an AND expression from two expressions
|
||||
/**
|
||||
Create an AND expression from two expressions.
|
||||
|
||||
SYNOPSIS
|
||||
and_expressions()
|
||||
a expression or NULL
|
||||
b expression.
|
||||
org_item Don't modify a if a == *org_item
|
||||
If a == NULL, org_item is set to point at b,
|
||||
to ensure that future calls will not modify b.
|
||||
@param a expression or NULL
|
||||
@param b expression.
|
||||
@param org_item Don't modify a if a == *org_item.
|
||||
If a == NULL, org_item is set to point at b,
|
||||
to ensure that future calls will not modify b.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
This will not modify item pointed to by org_item or b
|
||||
The idea is that one can call this in a loop and create and
|
||||
'and' over all items without modifying any of the original items.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
NULL Error
|
||||
@retval
|
||||
Item
|
||||
*/
|
||||
|
||||
|
|
@ -4234,7 +4234,9 @@ longlong Item_is_not_null_test::val_int()
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/* Optimize case of not_null_column IS NULL */
|
||||
/**
|
||||
Optimize case of not_null_column IS NULL.
|
||||
*/
|
||||
void Item_is_not_null_test::update_used_tables()
|
||||
{
|
||||
if (!args[0]->maybe_null)
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -4580,10 +4584,9 @@ void Item_func_regex::cleanup()
|
|||
#endif
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
turboBM_compute_suffixes()
|
||||
/**
|
||||
Precomputation dependent only on pattern_len.
|
||||
**********************************************************************/
|
||||
*/
|
||||
|
||||
void Item_func_like::turboBM_compute_suffixes(int *suff)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
@ -4711,10 +4712,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
|
|||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
turboBM_matches()
|
||||
Search for pattern in text, returns true/false for match/no match
|
||||
**********************************************************************/
|
||||
/**
|
||||
Search for pattern in text.
|
||||
|
||||
@return
|
||||
returns true/false for match/no match
|
||||
*/
|
||||
|
||||
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
||||
{
|
||||
|
|
@ -4794,24 +4797,20 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Make a logical XOR of the arguments.
|
||||
|
||||
SYNOPSIS
|
||||
val_int()
|
||||
|
||||
DESCRIPTION
|
||||
If either operator is NULL, return NULL.
|
||||
|
||||
NOTE
|
||||
As we don't do any index optimization on XOR this is not going to be
|
||||
very fast to use.
|
||||
|
||||
TODO (low priority)
|
||||
Change this to be optimized as:
|
||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
|
||||
@todo
|
||||
(low priority) Change this to be optimized as: @n
|
||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
|
||||
To be able to do this, we would however first have to extend the MySQL
|
||||
range optimizer to handle OR better.
|
||||
|
||||
@note
|
||||
As we don't do any index optimization on XOR this is not going to be
|
||||
very fast to use.
|
||||
*/
|
||||
|
||||
longlong Item_cond_xor::val_int()
|
||||
|
|
@ -4833,15 +4832,12 @@ longlong Item_cond_xor::val_int()
|
|||
return (longlong) result;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Apply NOT transformation to the item and return a new one.
|
||||
|
||||
SYNOPSIS
|
||||
neg_transformer()
|
||||
thd thread handler
|
||||
|
||||
DESCRIPTION
|
||||
Transform the item using next rules:
|
||||
@verbatim
|
||||
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
||||
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
||||
NOT(a) -> a
|
||||
|
|
@ -4853,8 +4849,11 @@ longlong Item_cond_xor::val_int()
|
|||
a <= b -> a > b
|
||||
IS NULL(a) -> IS NOT NULL(a)
|
||||
IS NOT NULL(a) -> IS NULL(a)
|
||||
@endverbatim
|
||||
|
||||
RETURN
|
||||
@param thd thread handler
|
||||
|
||||
@return
|
||||
New item or
|
||||
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
|
||||
*/
|
||||
|
|
@ -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= 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= 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]);
|
||||
}
|
||||
|
||||
// just fake method, should never be called
|
||||
/**
|
||||
just fake method, should never be called.
|
||||
*/
|
||||
Item *Item_bool_rowready_func2::negated_item()
|
||||
{
|
||||
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
|
||||
contains()
|
||||
field field whose occurrence is to be checked
|
||||
|
||||
DESCRIPTION
|
||||
The function checks whether field is occurred in the Item_equal object
|
||||
|
||||
RETURN VALUES
|
||||
The function checks whether field is occurred in the Item_equal object .
|
||||
|
||||
@param field field whose occurrence is to be checked
|
||||
|
||||
@retval
|
||||
1 if nultiple equality contains a reference to field
|
||||
0 otherwise
|
||||
@retval
|
||||
0 otherwise
|
||||
*/
|
||||
|
||||
bool Item_equal::contains(Field *field)
|
||||
|
|
@ -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.
|
||||
After this operation the Item_equal object additionally contains
|
||||
the field items of another item of the type Item_equal.
|
||||
If the optional constant items are not equal the cond_false flag is
|
||||
set to 1.
|
||||
|
||||
RETURN VALUES
|
||||
none
|
||||
@param item multiple equality whose members are to be joined
|
||||
*/
|
||||
|
||||
void Item_equal::merge(Item_equal *item)
|
||||
|
|
@ -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
|
||||
object according to the criteria determined by the cmp callback parameter.
|
||||
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
||||
placed after item_fiel2.
|
||||
|
||||
IMPLEMENTATION
|
||||
The function sorts field items by the exchange sort algorithm.
|
||||
The list of field items is looked through and whenever two neighboring
|
||||
members follow in a wrong order they are swapped. This is performed
|
||||
again and again until we get all members in a right order.
|
||||
|
||||
RETURN VALUES
|
||||
None
|
||||
|
||||
@param cmp function to compare field item
|
||||
@param arg context extra parameter for the cmp function
|
||||
*/
|
||||
|
||||
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
||||
|
|
@ -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 members of multiple equalities. Each new constant item is
|
||||
compared with the designated constant item if there is any in the
|
||||
multiple equality. If there is none the first new constant item
|
||||
becomes designated.
|
||||
|
||||
RETURN VALUES
|
||||
none
|
||||
*/
|
||||
|
||||
void Item_equal::update_const()
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* Functions to create an item. Used by sql_yacc.yy */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Functions to create an item. Used by sql_yac.yy
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "item_create.h"
|
||||
|
|
|
|||
297
sql/item_func.cc
297
sql/item_func.cc
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* This file defines all numerical functions */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
This file defines all numerical functions
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
|
|
@ -46,7 +51,10 @@ bool check_reserved_words(LEX_STRING *name)
|
|||
}
|
||||
|
||||
|
||||
/* return TRUE if item is a constant */
|
||||
/**
|
||||
@return
|
||||
TRUE if item is a constant
|
||||
*/
|
||||
|
||||
bool
|
||||
eval_const_cond(COND *cond)
|
||||
|
|
@ -237,25 +245,21 @@ void Item_func::traverse_cond(Cond_traverser traverser,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Transform an Item_func object with a transformer callback function
|
||||
|
||||
SYNOPSIS
|
||||
transform()
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
argument parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
/**
|
||||
Transform an Item_func object with a transformer callback function.
|
||||
|
||||
The function recursively applies the transform method to each
|
||||
argument of the Item_func node.
|
||||
If the call of the method for an argument item returns a new item
|
||||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_func object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
@param transformer the transformer callback function to be applied to
|
||||
the nodes of the tree of the object
|
||||
@param argument parameter to be passed to the transformer
|
||||
|
||||
@return
|
||||
Item returned as the result of transformation of the root node
|
||||
*/
|
||||
|
||||
Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||
|
|
@ -285,19 +289,10 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Compile Item_func object with a processor and a transformer callback functions
|
||||
|
||||
SYNOPSIS
|
||||
compile()
|
||||
analyzer the analyzer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg_p in/out parameter to be passed to the processor
|
||||
transformer the transformer callback function to be applied to the nodes
|
||||
of the tree of the object
|
||||
arg_t parameter to be passed to the transformer
|
||||
|
||||
DESCRIPTION
|
||||
/**
|
||||
Compile Item_func object with a processor and a transformer
|
||||
callback functions.
|
||||
|
||||
First the function applies the analyzer to the root node of
|
||||
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
||||
the function recursively applies the compile method to each argument
|
||||
|
|
@ -306,9 +301,16 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
|||
the old item is substituted for a new one.
|
||||
After this the transformer is applied to the root node
|
||||
of the Item_func object.
|
||||
|
||||
RETURN VALUES
|
||||
Item returned as the result of transformation of the root node
|
||||
|
||||
@param analyzer the analyzer callback function to be applied to the
|
||||
nodes of the tree of the object
|
||||
@param[in,out] arg_p parameter to be passed to the processor
|
||||
@param transformer the transformer callback function to be applied to the
|
||||
nodes of the tree of the object
|
||||
@param arg_t parameter to be passed to the transformer
|
||||
|
||||
@return
|
||||
Item returned as the result of transformation of the root node
|
||||
*/
|
||||
|
||||
Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||
|
|
@ -334,7 +336,9 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
|||
return (this->*transformer)(arg_t);
|
||||
}
|
||||
|
||||
/* See comments in Item_cmp_func::split_sum_func() */
|
||||
/**
|
||||
See comments in Item_cmp_func::split_sum_func()
|
||||
*/
|
||||
|
||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
List<Item> &fields)
|
||||
|
|
@ -523,12 +527,9 @@ void Item_func_numhybrid::fix_num_length_and_dec()
|
|||
{}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set max_length/decimals of function if function is fixed point and
|
||||
result length/precision depends on argument ones
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_decimal_length()
|
||||
result length/precision depends on argument ones.
|
||||
*/
|
||||
|
||||
void Item_func::count_decimal_length()
|
||||
|
|
@ -548,11 +549,8 @@ void Item_func::count_decimal_length()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Set max_length of if it is maximum length of its arguments
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_only_length()
|
||||
/**
|
||||
Set max_length of if it is maximum length of its arguments.
|
||||
*/
|
||||
|
||||
void Item_func::count_only_length()
|
||||
|
|
@ -567,12 +565,9 @@ void Item_func::count_only_length()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set max_length/decimals of function if function is floating point and
|
||||
result length/precision depends on argument ones
|
||||
|
||||
SYNOPSIS
|
||||
Item_func::count_real_length()
|
||||
result length/precision depends on argument ones.
|
||||
*/
|
||||
|
||||
void Item_func::count_real_length()
|
||||
|
|
@ -655,12 +650,9 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Check arguments here to determine result's type for a numeric
|
||||
function of two arguments.
|
||||
|
||||
SYNOPSIS
|
||||
Item_num_op::find_num_type()
|
||||
*/
|
||||
|
||||
void Item_num_op::find_num_type(void)
|
||||
|
|
@ -699,13 +691,10 @@ void Item_num_op::find_num_type(void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set result type for a numeric function of one argument
|
||||
(can be also used by a numeric function of many arguments, if the result
|
||||
type depends only on the first argument)
|
||||
|
||||
SYNOPSIS
|
||||
Item_func_num1::find_num_type()
|
||||
*/
|
||||
|
||||
void Item_func_num1::find_num_type()
|
||||
|
|
@ -1117,16 +1106,15 @@ longlong Item_func_plus::int_op()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Calculate plus of two decimail's
|
||||
/**
|
||||
Calculate plus of two decimals.
|
||||
|
||||
SYNOPSIS
|
||||
decimal_op()
|
||||
decimal_value Buffer that can be used to store result
|
||||
@param decimal_value Buffer that can be used to store result
|
||||
|
||||
RETURN
|
||||
0 Value was NULL; In this case null_value is set
|
||||
# Value of operation as a decimal
|
||||
@retval
|
||||
0 Value was NULL; In this case null_value is set
|
||||
@retval
|
||||
\# Value of operation as a decimal
|
||||
*/
|
||||
|
||||
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||
|
|
@ -1144,11 +1132,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Set precision of results for additive operations (+ and -)
|
||||
|
||||
SYNOPSIS
|
||||
Item_func_additive_op::result_precision()
|
||||
*/
|
||||
void Item_func_additive_op::result_precision()
|
||||
{
|
||||
|
|
@ -1167,7 +1152,7 @@ void Item_func_additive_op::result_precision()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
The following function is here to allow the user to force
|
||||
subtraction of UNSIGNED BIGINT to return negative values.
|
||||
*/
|
||||
|
|
@ -1199,7 +1184,9 @@ longlong Item_func_minus::int_op()
|
|||
}
|
||||
|
||||
|
||||
/* See Item_func_plus::decimal_op for comments */
|
||||
/**
|
||||
See Item_func_plus::decimal_op for comments.
|
||||
*/
|
||||
|
||||
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
|
|
@ -1238,7 +1225,7 @@ longlong Item_func_mul::int_op()
|
|||
}
|
||||
|
||||
|
||||
/* See Item_func_plus::decimal_op for comments */
|
||||
/** See Item_func_plus::decimal_op for comments. */
|
||||
|
||||
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
||||
{
|
||||
|
|
@ -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()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
|
@ -1589,10 +1576,11 @@ double Item_func_ln::val_real()
|
|||
return log(value);
|
||||
}
|
||||
|
||||
/*
|
||||
Extended but so slower LOG function
|
||||
We have to check if all values are > zero and first one is not one
|
||||
as these are the cases then result is not a number.
|
||||
/**
|
||||
Extended but so slower LOG function.
|
||||
|
||||
We have to check if all values are > zero and first one is not one
|
||||
as these are the cases then result is not a number.
|
||||
*/
|
||||
double Item_func_log::val_real()
|
||||
{
|
||||
|
|
@ -3021,8 +3009,10 @@ bool udf_handler::get_arguments()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* This returns (String*) 0 in case of NULL values */
|
||||
|
||||
/**
|
||||
@return
|
||||
(String*)NULL in case of NULL values
|
||||
*/
|
||||
String *udf_handler::val_str(String *str,String *save_str)
|
||||
{
|
||||
uchar is_null_tmp=0;
|
||||
|
|
@ -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
|
||||
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
|
||||
*/
|
||||
/**
|
||||
@note
|
||||
This has to come last in the udf_handler methods, or C for AIX
|
||||
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
|
||||
*/
|
||||
|
||||
udf_handler::~udf_handler()
|
||||
{
|
||||
|
|
@ -3327,10 +3318,10 @@ void item_user_lock_release(User_level_lock *ull)
|
|||
delete ull;
|
||||
}
|
||||
|
||||
/*
|
||||
Wait until we are at or past the given position in the master binlog
|
||||
on the slave
|
||||
*/
|
||||
/**
|
||||
Wait until we are at or past the given position in the master binlog
|
||||
on the slave.
|
||||
*/
|
||||
|
||||
longlong Item_master_pos_wait::val_int()
|
||||
{
|
||||
|
|
@ -3432,11 +3423,15 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
|||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Get a user level lock. If the thread has an old lock this is first released.
|
||||
Returns 1: Got lock
|
||||
Returns 0: Timeout
|
||||
Returns NULL: Error
|
||||
/**
|
||||
Get a user level lock. If the thread has an old lock this is first released.
|
||||
|
||||
@retval
|
||||
1 : Got lock
|
||||
@retval
|
||||
0 : Timeout
|
||||
@retval
|
||||
NULL : Error
|
||||
*/
|
||||
|
||||
longlong Item_func_get_lock::val_int()
|
||||
|
|
@ -3556,12 +3551,12 @@ longlong Item_func_get_lock::val_int()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Release a user level lock.
|
||||
Return:
|
||||
1 if lock released
|
||||
0 if lock wasn't held
|
||||
(SQL) NULL if no such lock
|
||||
@return
|
||||
- 1 if lock released
|
||||
- 0 if lock wasn't held
|
||||
- (SQL) NULL if no such lock
|
||||
*/
|
||||
|
||||
longlong Item_func_release_lock::val_int()
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
@ -3849,22 +3844,22 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set value to user variable.
|
||||
|
||||
SYNOPSYS
|
||||
update_hash()
|
||||
entry - pointer to structure representing variable
|
||||
set_null - should we set NULL value ?
|
||||
ptr - pointer to buffer with new value
|
||||
length - length of new value
|
||||
type - type of new value
|
||||
cs - charset info for new value
|
||||
dv - derivation for new value
|
||||
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
|
||||
@param entry pointer to structure representing variable
|
||||
@param set_null should we set NULL value ?
|
||||
@param ptr pointer to buffer with new value
|
||||
@param length length of new value
|
||||
@param type type of new value
|
||||
@param cs charset info for new value
|
||||
@param dv derivation for new value
|
||||
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||
|
||||
RETURN VALUE
|
||||
False - success, True - failure
|
||||
@retval
|
||||
false success
|
||||
@retval
|
||||
true failure
|
||||
*/
|
||||
|
||||
static bool
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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,
|
||||
uint decimals)
|
||||
|
|
@ -4039,7 +4034,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
|
|||
return(str);
|
||||
}
|
||||
|
||||
/* Get the value of a variable as a decimal */
|
||||
/** Get the value of a variable as a decimal. */
|
||||
|
||||
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
||||
{
|
||||
|
|
@ -4066,18 +4061,17 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
|||
return(val);
|
||||
}
|
||||
|
||||
/*
|
||||
This functions is invoked on SET @variable or @variable:= expression.
|
||||
/**
|
||||
This functions is invoked on SET \@variable or
|
||||
\@variable:= expression.
|
||||
|
||||
Evaluate (and check expression), store results.
|
||||
|
||||
SYNOPSYS
|
||||
Item_func_set_user_var::check()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
For now it always return OK. All problem with value evaluating
|
||||
will be caught by thd->is_error() check in sql_set_variables().
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
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
|
||||
Item_func_set_user_var::update()
|
||||
|
||||
NOTES
|
||||
@note
|
||||
We have to store the expression as such in the variable, independent of
|
||||
the value method used by the user
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
1 EOM Error
|
||||
|
||||
*/
|
||||
|
|
@ -4446,24 +4439,23 @@ longlong Item_func_get_user_var::val_int()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Get variable by name and, if necessary, put the record of variable
|
||||
use into the binary log.
|
||||
|
||||
SYNOPSIS
|
||||
get_var_with_binlog()
|
||||
thd Current thread
|
||||
name Variable name
|
||||
out_entry [out] variable structure or NULL. The pointer is set
|
||||
regardless of whether function succeeded or not.
|
||||
|
||||
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
||||
stores this variable and its value in thd->user_var_events, so that it can be
|
||||
written to the binlog (will be written just before the query is written, see
|
||||
log.cc).
|
||||
|
||||
RETURN
|
||||
@param thd Current thread
|
||||
@param name Variable name
|
||||
@param[out] out_entry variable structure or NULL. The pointer is set
|
||||
regardless of whether function succeeded or not.
|
||||
|
||||
@retval
|
||||
0 OK
|
||||
@retval
|
||||
1 Failed to put appropriate record into binary log
|
||||
|
||||
*/
|
||||
|
|
@ -5118,22 +5110,20 @@ longlong Item_func_bit_xor::val_int()
|
|||
System variables
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Return value of an system variable base[.name] as a constant item
|
||||
/**
|
||||
Return value of an system variable base[.name] as a constant item.
|
||||
|
||||
SYNOPSIS
|
||||
get_system_var()
|
||||
thd Thread handler
|
||||
var_type global / session
|
||||
name Name of base or system variable
|
||||
component Component
|
||||
@param thd Thread handler
|
||||
@param var_type global / session
|
||||
@param name Name of base or system variable
|
||||
@param component Component.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If component.str = 0 then the variable name is in 'name'
|
||||
|
||||
RETURN
|
||||
0 error
|
||||
# constant item
|
||||
@return
|
||||
- 0 : error
|
||||
- # : constant item
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -5173,16 +5163,15 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Check a user level lock.
|
||||
|
||||
SYNOPSIS:
|
||||
val_int()
|
||||
Sets null_value=TRUE on error.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 Available
|
||||
0 Already taken
|
||||
NULL Error
|
||||
@retval
|
||||
0 Already taken, or error
|
||||
*/
|
||||
|
||||
longlong Item_func_is_free_lock::val_int()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* This file defines all spatial functions */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
This file defines all spatial functions
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
|
|
@ -356,7 +361,7 @@ String *Item_func_point::val_str(String *str)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Concatenates various items into various collections
|
||||
with checkings for valid wkb type of items.
|
||||
For example, MultiPoint can be a collection of Points only.
|
||||
|
|
@ -538,6 +543,10 @@ longlong Item_func_isempty::val_int()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@todo
|
||||
Ramil or Holyfoot, add real IsSimple calculation
|
||||
*/
|
||||
longlong Item_func_issimple::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
|
|
|||
|
|
@ -15,13 +15,18 @@
|
|||
|
||||
#include "mysql_priv.h"
|
||||
|
||||
/*
|
||||
/**
|
||||
Row items used for comparing rows and IN operations on rows:
|
||||
|
||||
@verbatim
|
||||
(a, b, c) > (10, 10, 30)
|
||||
(a, b, c) = (select c, d, e, from t1 where x=12)
|
||||
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
|
||||
(a, b, c) IN (select c, d, e, from t1)
|
||||
@endverbatim
|
||||
|
||||
@todo
|
||||
think placing 2-3 component items in item (as it done for function
|
||||
*/
|
||||
|
||||
Item_row::Item_row(List<Item> &arg):
|
||||
|
|
|
|||
|
|
@ -14,9 +14,15 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* This file defines all string functions
|
||||
** Warning: Some string functions doesn't always put and end-null on a String
|
||||
** (This shouldn't be needed)
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
This file defines all string functions
|
||||
|
||||
@warning
|
||||
Some string functions don't always put and end-null on a String.
|
||||
(This shouldn't be needed)
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
|
|
@ -267,9 +273,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Concatenate args with the following premises:
|
||||
If only one arg (which is ok), return value of arg
|
||||
If only one arg (which is ok), return value of arg;
|
||||
Don't reallocate val_str() if not absolute necessary.
|
||||
*/
|
||||
|
||||
|
|
@ -425,13 +431,15 @@ void Item_func_concat::fix_length_and_dec()
|
|||
max_length= (ulong) max_result_length;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
Function des_encrypt() by tonu@spam.ee & monty
|
||||
Works only if compiled with OpenSSL library support.
|
||||
This returns a binary string where first character is CHAR(128 | key-number).
|
||||
If one uses a string key key_number is 127.
|
||||
Encryption result is longer than original by formula:
|
||||
new_length= org_length + (8-(org_length % 8))+1
|
||||
@return
|
||||
A binary string where first character is CHAR(128 | key-number).
|
||||
If one uses a string key key_number is 127.
|
||||
Encryption result is longer than original by formula:
|
||||
@code new_length= org_length + (8-(org_length % 8))+1 @endcode
|
||||
*/
|
||||
|
||||
String *Item_func_des_encrypt::val_str(String *str)
|
||||
|
|
@ -604,7 +612,7 @@ wrong_key:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
concat with separator. First arg is the separator
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
** Replace all occurences of string2 in string1 with string3.
|
||||
** Don't reallocate val_str() if not needed
|
||||
*/
|
||||
/**
|
||||
Replace all occurences of string2 in string1 with string3.
|
||||
|
||||
/* TODO: Fix that this works with binary strings when using USE_MB */
|
||||
Don't reallocate val_str() if not needed.
|
||||
|
||||
@todo
|
||||
Fix that this works with binary strings when using USE_MB
|
||||
*/
|
||||
|
||||
String *Item_func_replace::val_str(String *str)
|
||||
{
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -1857,7 +1868,7 @@ void Item_func_soundex::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
If alpha, map input letter to soundex code.
|
||||
If not alpha and remove_garbage is set then skip to next char
|
||||
else return 0
|
||||
|
|
@ -2001,9 +2012,10 @@ String *Item_func_soundex::val_str(String *str)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** Change a number to format '3,333,333,333.000'
|
||||
** This should be 'internationalized' sometimes.
|
||||
/**
|
||||
Change a number to format '3,333,333,333.000'.
|
||||
|
||||
This should be 'internationalized' sometimes.
|
||||
*/
|
||||
|
||||
const int FORMAT_MAX_DECIMALS= 30;
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
@ -2370,9 +2383,9 @@ void Item_func_repeat::fix_length_and_dec()
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Item_func_repeat::str is carefully written to avoid reallocs
|
||||
** as much as possible at the cost of a local buffer
|
||||
/**
|
||||
Item_func_repeat::str is carefully written to avoid reallocs
|
||||
as much as possible at the cost of a local buffer
|
||||
*/
|
||||
|
||||
String *Item_func_repeat::val_str(String *str)
|
||||
|
|
@ -2848,7 +2861,7 @@ String *Item_func_hex::val_str(String *str)
|
|||
return &tmp_value;
|
||||
}
|
||||
|
||||
/* Convert given hex string to a binary string */
|
||||
/** Convert given hex string to a binary string. */
|
||||
|
||||
String *Item_func_unhex::val_str(String *str)
|
||||
{
|
||||
|
|
@ -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
|
||||
using in a SQL statement.
|
||||
|
||||
DESCRIPTION
|
||||
Adds a \ before all characters that needs to be escaped in a SQL string.
|
||||
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
||||
running commands from a file in windows.
|
||||
Adds a \\ before all characters that needs to be escaped in a SQL string.
|
||||
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
||||
running commands from a file in windows.
|
||||
|
||||
This function is very useful when you want to generate SQL statements
|
||||
This function is very useful when you want to generate SQL statements.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
||||
|
||||
RETURN VALUES
|
||||
str Quoted string
|
||||
NULL Out of memory.
|
||||
@retval
|
||||
str Quoted string
|
||||
@retval
|
||||
NULL Out of memory.
|
||||
*/
|
||||
|
||||
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
||||
|
||||
String *Item_func_quote::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
|
@ -3347,8 +3360,10 @@ static uint nanoseq;
|
|||
static ulonglong uuid_time=0;
|
||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||
|
||||
/* number of 100-nanosecond intervals between
|
||||
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
|
||||
/**
|
||||
number of 100-nanosecond intervals between
|
||||
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
|
||||
*/
|
||||
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
||||
|
||||
#define UUID_VERSION 0x1000
|
||||
|
|
|
|||
|
|
@ -13,12 +13,15 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
subselect Item
|
||||
/**
|
||||
@file
|
||||
|
||||
SUBSELECT TODO:
|
||||
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
||||
(sql_select.h/sql_select.cc)
|
||||
@brief
|
||||
subselect Item
|
||||
|
||||
@todo
|
||||
- add function from mysql_select that use JOIN* as parameter to JOIN
|
||||
methods (sql_select.h/sql_select.cc)
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
|
|
@ -403,6 +406,16 @@ void Item_singlerow_subselect::reset()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@todo
|
||||
- We cant change name of Item_field or Item_ref, because it will
|
||||
prevent it's correct resolving, but we should save name of
|
||||
removed item => we do not make optimization if top item of
|
||||
list is field or reference.
|
||||
- switch off this optimization for prepare statement,
|
||||
because we do not rollback this changes.
|
||||
Make rollback for it, or special name resolving mode in 5.0.
|
||||
*/
|
||||
Item_subselect::trans_res
|
||||
Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||
{
|
||||
|
|
@ -1445,24 +1458,24 @@ Item_in_subselect::select_transformer(JOIN *join)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
||||
transformation function
|
||||
transformation function.
|
||||
|
||||
SYNOPSIS
|
||||
Item_in_subselect::select_in_like_transformer()
|
||||
join JOIN object of transforming subquery
|
||||
func creator of condition function of subquery
|
||||
|
||||
DESCRIPTION
|
||||
To decide which transformation procedure (scalar or row) applicable here
|
||||
we have to call fix_fields() for left expression to be able to call
|
||||
cols() method on it. Also this method make arena management for
|
||||
underlying transformation methods.
|
||||
|
||||
RETURN
|
||||
@param join JOIN object of transforming subquery
|
||||
@param func creator of condition function of subquery
|
||||
|
||||
@retval
|
||||
RES_OK OK
|
||||
RES_REDUCE OK, and current subquery was reduced during transformation
|
||||
@retval
|
||||
RES_REDUCE OK, and current subquery was reduced during
|
||||
transformation
|
||||
@retval
|
||||
RES_ERROR Error
|
||||
*/
|
||||
|
||||
|
|
@ -2423,16 +2436,15 @@ void subselect_indexsubquery_engine::print(String *str)
|
|||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
change select_result object of engine
|
||||
/**
|
||||
change select_result object of engine.
|
||||
|
||||
SYNOPSIS
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
@param si new subselect Item
|
||||
@param res new select_result object
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
subselect_single_select_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
bool subselect_single_select_engine::no_tables()
|
||||
|
|
@ -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
|
||||
subselect_union_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
bool subselect_union_engine::no_tables()
|
||||
|
|
@ -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
|
||||
subselect_uniquesubquery_engine::no_tables()
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
TRUE there are not tables used in subquery
|
||||
@retval
|
||||
FALSE there are some tables in subquery
|
||||
*/
|
||||
|
||||
|
|
|
|||
153
sql/item_sum.cc
153
sql/item_sum.cc
|
|
@ -14,7 +14,12 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* Sum functions (COUNT, MIN...) */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Sum functions (COUNT, MIN...)
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
|
|
@ -23,28 +28,25 @@
|
|||
#include "mysql_priv.h"
|
||||
#include "sql_select.h"
|
||||
|
||||
/*
|
||||
Prepare an aggregate function item for checking context conditions
|
||||
/**
|
||||
Prepare an aggregate function item for checking context conditions.
|
||||
|
||||
SYNOPSIS
|
||||
init_sum_func_check()
|
||||
thd reference to the thread context info
|
||||
|
||||
DESCRIPTION
|
||||
The function initializes the members of the Item_sum object created
|
||||
for a set function that are used to check validity of the set function
|
||||
occurrence.
|
||||
If the set function is not allowed in any subquery where it occurs
|
||||
an error is reported immediately.
|
||||
|
||||
NOTES
|
||||
@param thd reference to the thread context info
|
||||
|
||||
@note
|
||||
This function is to be called for any item created for a set function
|
||||
object when the traversal of trees built for expressions used in the query
|
||||
is performed at the phase of context analysis. This function is to
|
||||
be invoked at the descent of this traversal.
|
||||
|
||||
RETURN
|
||||
TRUE if an error is reported
|
||||
@retval
|
||||
TRUE if an error is reported
|
||||
@retval
|
||||
FALSE otherwise
|
||||
*/
|
||||
|
||||
|
|
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Check constraints imposed on a usage of a set function
|
||||
/**
|
||||
Check constraints imposed on a usage of a set function.
|
||||
|
||||
SYNOPSIS
|
||||
check_sum_func()
|
||||
thd reference to the thread context info
|
||||
ref location of the pointer to this item in the embedding expression
|
||||
|
||||
DESCRIPTION
|
||||
The method verifies whether context conditions imposed on a usage
|
||||
of any set function are met for this occurrence.
|
||||
It checks whether the set function occurs in the position where it
|
||||
|
|
@ -89,13 +85,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
adds it to the chain of items for such set functions that is attached
|
||||
to the the st_select_lex structure for this subquery.
|
||||
|
||||
NOTES
|
||||
This function is to be called for any item created for a set function
|
||||
object when the traversal of trees built for expressions used in the query
|
||||
is performed at the phase of context analysis. This function is to
|
||||
be invoked at the ascent of this traversal.
|
||||
|
||||
IMPLEMENTATION
|
||||
A number of designated members of the object are used to check the
|
||||
conditions. They are specified in the comment before the Item_sum
|
||||
class declaration.
|
||||
|
|
@ -106,16 +95,28 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
|||
of set functions are allowed (i.e either in the SELECT list or
|
||||
in the HAVING clause of the corresponding subquery)
|
||||
Consider the query:
|
||||
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
||||
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
|
||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
||||
@code
|
||||
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
||||
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
|
||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
||||
@endcode
|
||||
allow_sum_func will contain:
|
||||
for SUM(t1.b) - 1 at the first position
|
||||
for AVG(t1.b) - 1 at the first position, 0 at the second position
|
||||
for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
||||
- for SUM(t1.b) - 1 at the first position
|
||||
- for AVG(t1.b) - 1 at the first position, 0 at the second position
|
||||
- for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
||||
|
||||
RETURN
|
||||
TRUE if an error is reported
|
||||
@param thd reference to the thread context info
|
||||
@param ref location of the pointer to this item in the embedding expression
|
||||
|
||||
@note
|
||||
This function is to be called for any item created for a set function
|
||||
object when the traversal of trees built for expressions used in the query
|
||||
is performed at the phase of context analysis. This function is to
|
||||
be invoked at the ascent of this traversal.
|
||||
|
||||
@retval
|
||||
TRUE if an error is reported
|
||||
@retval
|
||||
FALSE otherwise
|
||||
*/
|
||||
|
||||
|
|
@ -200,15 +201,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Attach a set function to the subquery where it must be aggregated
|
||||
/**
|
||||
Attach a set function to the subquery where it must be aggregated.
|
||||
|
||||
SYNOPSIS
|
||||
register_sum_func()
|
||||
thd reference to the thread context info
|
||||
ref location of the pointer to this item in the embedding expression
|
||||
|
||||
DESCRIPTION
|
||||
The function looks for an outer subquery where the set function must be
|
||||
aggregated. If it finds such a subquery then aggr_level is set to
|
||||
the nest level of this subquery and the item for the set function
|
||||
|
|
@ -216,14 +211,18 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
|||
inner_sum_func_list defined for each subquery. When the item is placed
|
||||
there the field 'ref_by' is set to ref.
|
||||
|
||||
NOTES.
|
||||
@note
|
||||
Now we 'register' only set functions that are aggregated in outer
|
||||
subqueries. Actually it makes sense to link all set function for
|
||||
a subquery in one chain. It would simplify the process of 'splitting'
|
||||
for set functions.
|
||||
|
||||
RETURN
|
||||
@param thd reference to the thread context info
|
||||
@param ref location of the pointer to this item in the embedding expression
|
||||
|
||||
@retval
|
||||
FALSE if the executes without failures (currently always)
|
||||
@retval
|
||||
TRUE otherwise
|
||||
*/
|
||||
|
||||
|
|
@ -311,8 +310,8 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Constructor used in processing select with temporary tebles
|
||||
/**
|
||||
Constructor used in processing select with temporary tebles.
|
||||
*/
|
||||
|
||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||
|
|
@ -655,6 +654,10 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
|
|||
** reset and add of sum_func
|
||||
***********************************************************************/
|
||||
|
||||
/**
|
||||
@todo
|
||||
check if the following assignments are really needed
|
||||
*/
|
||||
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
|
||||
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
|
||||
curr_dec_buff(item->curr_dec_buff)
|
||||
|
|
@ -833,7 +836,7 @@ Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Behaves like an Integer except to fix_length_and_dec().
|
||||
Additionally div() converts val with this traits to a val with true
|
||||
decimal traits along with conversion of integer value to decimal value.
|
||||
|
|
@ -910,6 +913,10 @@ void Item_sum_distinct::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@todo
|
||||
check that the case of CHAR(0) works OK
|
||||
*/
|
||||
bool Item_sum_distinct::setup(THD *thd)
|
||||
{
|
||||
List<Create_field> field_list;
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Did not make this one static - at least gcc gets confused when
|
||||
I try to declare a static function as a friend. If you can figure
|
||||
out the syntax to make a static function a friend, make this one
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
|
@ -2854,9 +2868,8 @@ String *Item_sum_udf_str::val_str(String *str)
|
|||
Blobs doesn't work with DISTINCT or ORDER BY
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
function of sort for syntax:
|
||||
GROUP_CONCAT(DISTINCT expr,...)
|
||||
/**
|
||||
function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...)
|
||||
*/
|
||||
|
||||
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
||||
|
|
@ -2893,9 +2906,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
function of sort for syntax:
|
||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||
/**
|
||||
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||
*/
|
||||
|
||||
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
||||
|
|
@ -2937,11 +2949,11 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
function of sort for syntax:
|
||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ).
|
||||
|
||||
BUG:
|
||||
@bug
|
||||
This doesn't work in the case when the order by contains data that
|
||||
is not part of the field list because tree-insert will not notice
|
||||
the duplicated values when inserting things sorted by ORDER BY
|
||||
|
|
@ -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)),
|
||||
|
|
@ -3028,12 +3040,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Constructor of Item_func_group_concat
|
||||
distinct_arg - distinct
|
||||
select_list - list of expression for show values
|
||||
order_list - list of sort columns
|
||||
separator_arg - string value of separator
|
||||
/**
|
||||
Constructor of Item_func_group_concat.
|
||||
|
||||
@param distinct_arg distinct
|
||||
@param select_list list of expression for show values
|
||||
@param order_list list of sort columns
|
||||
@param separator_arg string value of separator.
|
||||
*/
|
||||
|
||||
Item_func_group_concat::
|
||||
|
|
|
|||
|
|
@ -14,7 +14,15 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* This file defines all time functions */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
This file defines all time functions
|
||||
|
||||
@todo
|
||||
Move month and days to language files
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||
#pragma implementation // gcc: Class implementation
|
||||
|
|
@ -24,17 +32,16 @@
|
|||
#include <m_ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
/* TODO: Move month and days to language files */
|
||||
|
||||
/* Day number for Dec 31st, 9999 */
|
||||
/** Day number for Dec 31st, 9999. */
|
||||
#define MAX_DAY_NUMBER 3652424L
|
||||
|
||||
/*
|
||||
OPTIMIZATION TODO:
|
||||
- Replace the switch with a function that should be called for each
|
||||
date type.
|
||||
- Remove sprintf and opencode the conversion, like we do in
|
||||
Field_datetime.
|
||||
/**
|
||||
@todo
|
||||
OPTIMIZATION
|
||||
- Replace the switch with a function that should be called for each
|
||||
date type.
|
||||
- Remove sprintf and opencode the conversion, like we do in
|
||||
Field_datetime.
|
||||
|
||||
The reason for this functions existence is that as we don't have a
|
||||
way to know if a datetime/time value has microseconds in them
|
||||
|
|
@ -226,37 +233,37 @@ static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0,
|
|||
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
||||
{(char *)"%H:%i:%S", 8}};
|
||||
|
||||
/*
|
||||
/**
|
||||
Extract datetime value to MYSQL_TIME struct from string value
|
||||
according to format string.
|
||||
according to format string.
|
||||
|
||||
SYNOPSIS
|
||||
extract_date_time()
|
||||
format date/time format specification
|
||||
val String to decode
|
||||
length Length of string
|
||||
l_time Store result here
|
||||
cached_timestamp_type
|
||||
It uses to get an appropriate warning
|
||||
in the case when the value is truncated.
|
||||
sub_pattern_end if non-zero then we are parsing string which
|
||||
should correspond compound specifier (like %T or
|
||||
%r) and this parameter is pointer to place where
|
||||
pointer to end of string matching this specifier
|
||||
should be stored.
|
||||
NOTE
|
||||
Possibility to parse strings matching to patterns equivalent to compound
|
||||
specifiers is mainly intended for use from inside of this function in
|
||||
order to understand %T and %r conversion specifiers, so number of
|
||||
conversion specifiers that can be used in such sub-patterns is limited.
|
||||
Also most of checks are skipped in this case.
|
||||
@param format date/time format specification
|
||||
@param val String to decode
|
||||
@param length Length of string
|
||||
@param l_time Store result here
|
||||
@param cached_timestamp_type It uses to get an appropriate warning
|
||||
in the case when the value is truncated.
|
||||
@param sub_pattern_end if non-zero then we are parsing string which
|
||||
should correspond compound specifier (like %T or
|
||||
%r) and this parameter is pointer to place where
|
||||
pointer to end of string matching this specifier
|
||||
should be stored.
|
||||
|
||||
If one adds new format specifiers to this function he should also
|
||||
consider adding them to get_date_time_result_type() function.
|
||||
@note
|
||||
Possibility to parse strings matching to patterns equivalent to compound
|
||||
specifiers is mainly intended for use from inside of this function in
|
||||
order to understand %T and %r conversion specifiers, so number of
|
||||
conversion specifiers that can be used in such sub-patterns is limited.
|
||||
Also most of checks are skipped in this case.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
@note
|
||||
If one adds new format specifiers to this function he should also
|
||||
consider adding them to get_date_time_result_type() function.
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||
|
|
@ -603,8 +610,8 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a formated date/time value in a string
|
||||
/**
|
||||
Create a formated date/time value in a string.
|
||||
*/
|
||||
|
||||
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||
|
|
@ -838,7 +845,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
Get a array of positive numbers from a string object.
|
||||
Each number is separated by 1 non digit character
|
||||
Return error if there is too many numbers.
|
||||
|
|
@ -846,16 +854,14 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
|||
from the high end. This allows one to give:
|
||||
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||
|
||||
SYNOPSIS
|
||||
str: string value
|
||||
length: length of str
|
||||
cs: charset of str
|
||||
values: array of results
|
||||
count: count of elements in result array
|
||||
transform_msec: if value is true we suppose
|
||||
that the last part of string value is microseconds
|
||||
and we should transform value to six digit value.
|
||||
For example, '1.1' -> '1.100000'
|
||||
@param length: length of str
|
||||
@param cs: charset of str
|
||||
@param values: array of results
|
||||
@param count: count of elements in result array
|
||||
@param transform_msec: if value is true we suppose
|
||||
that the last part of string value is microseconds
|
||||
and we should transform value to six digit value.
|
||||
For example, '1.1' -> '1.100000'
|
||||
*/
|
||||
|
||||
static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||
|
|
@ -1046,7 +1052,9 @@ String* Item_func_monthname::val_str(String* str)
|
|||
}
|
||||
|
||||
|
||||
// Returns the quarter of the year
|
||||
/**
|
||||
Returns the quarter of the year.
|
||||
*/
|
||||
|
||||
longlong Item_func_quarter::val_int()
|
||||
{
|
||||
|
|
@ -1072,8 +1080,10 @@ longlong Item_func_minute::val_int()
|
|||
(void) get_arg0_time(<ime);
|
||||
return ltime.minute;
|
||||
}
|
||||
// Returns the second in time_exp in the range of 0 - 59
|
||||
|
||||
/**
|
||||
Returns the second in time_exp in the range of 0 - 59.
|
||||
*/
|
||||
longlong Item_func_second::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
|
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
|
|||
return week_format;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
@verbatim
|
||||
The bits in week_format(for calc_week() function) has the following meaning:
|
||||
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
|
||||
If set Monday is first day of week
|
||||
|
|
@ -1118,6 +1129,7 @@ uint week_mode(uint mode)
|
|||
four or more days in the new year, then it is week 1;
|
||||
Otherwise it is the last week of the previous year, and the
|
||||
next week is week 1.
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
longlong Item_func_week::val_int()
|
||||
|
|
@ -1281,8 +1293,9 @@ longlong Item_func_time_to_sec::val_int()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert a string to a interval value
|
||||
/**
|
||||
Convert a string to a interval value.
|
||||
|
||||
To make code easy, allow interval objects without separators.
|
||||
*/
|
||||
|
||||
|
|
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||
time zone. Defines time zone (local) used for whole CURDATE function.
|
||||
*/
|
||||
|
|
@ -1519,7 +1532,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
|
||||
*/
|
||||
|
|
@ -1563,7 +1576,7 @@ void Item_func_curtime::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||
time zone. Defines time zone (local) used for whole CURTIME function.
|
||||
*/
|
||||
|
|
@ -1576,7 +1589,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
|
||||
*/
|
||||
|
|
@ -1612,7 +1625,7 @@ void Item_func_now::fix_length_and_dec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||
time zone. Defines time zone (local) used for whole NOW function.
|
||||
*/
|
||||
|
|
@ -1625,7 +1638,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
|
||||
*/
|
||||
|
|
@ -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
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
MAKEDATE(a,b) is a date function that creates a date 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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
||||
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
|
||||
time value between a start and end time.
|
||||
|
||||
|
|
@ -2880,7 +2893,7 @@ null_date:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
MAKETIME(h,m,s) is a time function that calculates a time value
|
||||
from the total number of hours, minutes, and seconds.
|
||||
Result: Time value
|
||||
|
|
@ -2947,7 +2960,7 @@ String *Item_func_maketime::val_str(String *str)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
|
||||
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
|
||||
according to format string.
|
||||
|
||||
SYNOPSIS
|
||||
get_date_time_result_type()
|
||||
format - format string
|
||||
length - length of format string
|
||||
@param format format string
|
||||
@param length length of format string
|
||||
|
||||
NOTE
|
||||
@note
|
||||
We don't process day format's characters('D', 'd', 'e') because day
|
||||
may be a member of all date/time types.
|
||||
|
||||
@note
|
||||
Format specifiers supported by this function should be in sync with
|
||||
specifiers supported by extract_date_time() function.
|
||||
|
||||
RETURN VALUE
|
||||
@return
|
||||
One of date_time_format_types values:
|
||||
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
|
||||
- DATE_TIME_MICROSECOND
|
||||
- DATE_TIME
|
||||
- DATE_ONLY
|
||||
- TIME_MICROSECOND
|
||||
- TIME_ONLY
|
||||
*/
|
||||
|
||||
static date_time_format_types
|
||||
|
|
|
|||
86
sql/key.cc
86
sql/key.cc
|
|
@ -90,25 +90,19 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Copy part of a record that forms a key or key prefix to a buffer.
|
||||
|
||||
SYNOPSIS
|
||||
key_copy()
|
||||
to_key buffer that will be used as a key
|
||||
from_record full record to be copied from
|
||||
key_info descriptor of the index
|
||||
key_length specifies length of all keyparts that will be copied
|
||||
|
||||
DESCRIPTION
|
||||
The function takes a complete table record (as e.g. retrieved by
|
||||
handler::index_read()), and a description of an index on the same table,
|
||||
and extracts the first key_length bytes of the record which are part of a
|
||||
key into to_key. If length == 0 then copy all bytes from the record that
|
||||
form a key.
|
||||
|
||||
RETURN
|
||||
None
|
||||
@param to_key buffer that will be used as a key
|
||||
@param from_record full record to be copied from
|
||||
@param key_info descriptor of the index
|
||||
@param key_length specifies length of all keyparts that will be copied
|
||||
*/
|
||||
|
||||
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
||||
|
|
@ -163,22 +157,16 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Restore a key from some buffer to record.
|
||||
|
||||
SYNOPSIS
|
||||
key_restore()
|
||||
to_record record buffer where the key will be restored to
|
||||
from_key buffer that contains a key
|
||||
key_info descriptor of the index
|
||||
key_length specifies length of all keyparts that will be restored
|
||||
|
||||
DESCRIPTION
|
||||
This function converts a key into record format. It can be used in cases
|
||||
when we want to return a key as a result row.
|
||||
|
||||
RETURN
|
||||
None
|
||||
@param to_record record buffer where the key will be restored to
|
||||
@param from_key buffer that contains a key
|
||||
@param key_info descriptor of the index
|
||||
@param key_length specifies length of all keyparts that will be restored
|
||||
*/
|
||||
|
||||
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
||||
|
|
@ -255,24 +243,23 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Compare if a key has changed
|
||||
/**
|
||||
Compare if a key has changed.
|
||||
|
||||
SYNOPSIS
|
||||
key_cmp_if_same()
|
||||
table TABLE
|
||||
key key to compare to row
|
||||
idx Index used
|
||||
key_length Length of key
|
||||
@param table TABLE
|
||||
@param key key to compare to row
|
||||
@param idx Index used
|
||||
@param key_length Length of key
|
||||
|
||||
NOTES
|
||||
@note
|
||||
In theory we could just call field->cmp() for all field types,
|
||||
but as we are only interested if a key has changed (not if the key is
|
||||
larger or smaller than the previous value) we can do things a bit
|
||||
faster by using memcmp() instead.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 If key is equal
|
||||
@retval
|
||||
1 Key has changed
|
||||
*/
|
||||
|
||||
|
|
@ -331,17 +318,17 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
|
|||
}
|
||||
|
||||
/*
|
||||
unpack key-fields from record to some buffer
|
||||
unpack key-fields from record to some buffer.
|
||||
|
||||
SYNOPSIS
|
||||
key_unpack()
|
||||
This is used mainly to get a good error message. We temporary
|
||||
change the column bitmap so that all columns are readable.
|
||||
|
||||
@param
|
||||
to Store value here in an easy to read form
|
||||
@param
|
||||
table Table to use
|
||||
@param
|
||||
idx Key number
|
||||
|
||||
NOTES
|
||||
This is used mainly to get a good error message
|
||||
We temporary change the column bitmap so that all columns are readable.
|
||||
*/
|
||||
|
||||
void key_unpack(String *to,TABLE *table,uint idx)
|
||||
|
|
@ -419,21 +406,18 @@ bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Compare key in row to a given key
|
||||
/**
|
||||
Compare key in row to a given key.
|
||||
|
||||
SYNOPSIS
|
||||
key_cmp()
|
||||
key_part Key part handler
|
||||
key Key to compare to value in table->record[0]
|
||||
key_length length of 'key'
|
||||
@param key_part Key part handler
|
||||
@param key Key to compare to value in table->record[0]
|
||||
@param key_length length of 'key'
|
||||
|
||||
RETURN
|
||||
@return
|
||||
The return value is SIGN(key_in_row - range_key):
|
||||
|
||||
0 Key is equal to range or 'range' == 0 (no range)
|
||||
-1 Key is less than range
|
||||
1 Key is larger than range
|
||||
- 0 Key is equal to range or 'range' == 0 (no range)
|
||||
- -1 Key is less than range
|
||||
- 1 Key is larger than range
|
||||
*/
|
||||
|
||||
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
||||
|
|
|
|||
217
sql/lock.cc
217
sql/lock.cc
|
|
@ -14,8 +14,11 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* locking functions for mysql */
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
Locking functions for mysql.
|
||||
|
||||
Because of the new concurrent inserts, we must first get external locks
|
||||
before getting internal locks. If we do it in the other order, the status
|
||||
information is not up to date when called from the lock handler.
|
||||
|
|
@ -65,7 +68,7 @@
|
|||
excluding one that caused failure. That means handler must cleanup itself
|
||||
in case external_lock() fails.
|
||||
|
||||
TODO:
|
||||
@todo
|
||||
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
||||
we are forced to use mysql_lock_merge.
|
||||
*/
|
||||
|
|
@ -390,10 +393,11 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Unlock some of the tables locked by mysql_lock_tables
|
||||
/**
|
||||
Unlock some of the tables locked by mysql_lock_tables.
|
||||
|
||||
This will work even if get_lock_data fails (next unlock will free all)
|
||||
*/
|
||||
*/
|
||||
|
||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
||||
{
|
||||
|
|
@ -405,8 +409,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
** unlock all tables locked for read.
|
||||
/**
|
||||
unlock all tables locked for read.
|
||||
*/
|
||||
|
||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||
|
|
@ -567,7 +571,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
|
|||
}
|
||||
|
||||
|
||||
/* abort all other threads waiting to get lock in table */
|
||||
/** Abort all other threads waiting to get lock in table. */
|
||||
|
||||
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
||||
{
|
||||
|
|
@ -586,16 +590,15 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Abort one thread / table combination
|
||||
/**
|
||||
Abort one thread / table combination.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_lock_abort_for_thread()
|
||||
thd Thread handler
|
||||
table Table that should be removed from lock queue
|
||||
@param thd Thread handler
|
||||
@param table Table that should be removed from lock queue
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 Table was not locked by another thread
|
||||
@retval
|
||||
1 Table was locked by at least one other thread
|
||||
*/
|
||||
|
||||
|
|
@ -663,28 +666,27 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Find duplicate lock in tables.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_lock_have_duplicate()
|
||||
thd The current thread.
|
||||
needle The table to check for duplicate lock.
|
||||
haystack The list of tables to search for the dup lock.
|
||||
Temporary tables are ignored here like they are ignored in
|
||||
get_lock_data(). If we allow two opens on temporary tables later,
|
||||
both functions should be checked.
|
||||
|
||||
NOTE
|
||||
@param thd The current thread.
|
||||
@param needle The table to check for duplicate lock.
|
||||
@param haystack The list of tables to search for the dup lock.
|
||||
|
||||
@note
|
||||
This is mainly meant for MERGE tables in INSERT ... SELECT
|
||||
situations. The 'real', underlying tables can be found only after
|
||||
the MERGE tables are opened. This function assumes that the tables are
|
||||
already locked.
|
||||
|
||||
Temporary tables are ignored here like they are ignored in
|
||||
get_lock_data(). If we allow two opens on temporary tables later,
|
||||
both functions should be checked.
|
||||
|
||||
RETURN
|
||||
NULL No duplicate lock found.
|
||||
! NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||
@retval
|
||||
NULL No duplicate lock found.
|
||||
@retval
|
||||
!NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||
*/
|
||||
|
||||
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||
|
|
@ -768,7 +770,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
|||
}
|
||||
|
||||
|
||||
/* unlock a set of external */
|
||||
/** Unlock a set of external. */
|
||||
|
||||
static int unlock_external(THD *thd, TABLE **table,uint count)
|
||||
{
|
||||
|
|
@ -793,21 +795,17 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Get lock structures from table structs and initialize locks
|
||||
/**
|
||||
Get lock structures from table structs and initialize locks.
|
||||
|
||||
SYNOPSIS
|
||||
get_lock_data()
|
||||
thd Thread handler
|
||||
table_ptr Pointer to tables that should be locks
|
||||
flags One of:
|
||||
GET_LOCK_UNLOCK: If we should send TL_IGNORE to
|
||||
store lock
|
||||
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
|
||||
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||
@param thd Thread handler
|
||||
@param table_ptr Pointer to tables that should be locks
|
||||
@param flags One of:
|
||||
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
|
||||
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
|
||||
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||
*/
|
||||
|
||||
|
||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||
uint flags, TABLE **write_lock_used)
|
||||
{
|
||||
|
|
@ -893,31 +891,25 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Reset lock type in lock data.
|
||||
|
||||
SYNOPSIS
|
||||
reset_lock_data()
|
||||
sql_lock The MySQL lock.
|
||||
After a locking error we want to quit the locking of the table(s).
|
||||
The test case in the bug report for Bug #18544 has the following
|
||||
cases:
|
||||
-# Locking error in lock_external() due to InnoDB timeout.
|
||||
-# Locking error in get_lock_data() due to missing write permission.
|
||||
-# Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||
|
||||
DESCRIPTION
|
||||
In all these cases we have already set the lock type into the lock
|
||||
data of the open table(s). If the table(s) are in the open table
|
||||
cache, they could be reused with the non-zero lock type set. This
|
||||
could lead to ignoring a different lock type with the next lock.
|
||||
|
||||
After a locking error we want to quit the locking of the table(s).
|
||||
The test case in the bug report for Bug #18544 has the following
|
||||
cases: 1. Locking error in lock_external() due to InnoDB timeout.
|
||||
2. Locking error in get_lock_data() due to missing write permission.
|
||||
3. Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||
Clear the lock type of all lock data. This ensures that the next
|
||||
lock request will set its lock type properly.
|
||||
|
||||
In all these cases we have already set the lock type into the lock
|
||||
data of the open table(s). If the table(s) are in the open table
|
||||
cache, they could be reused with the non-zero lock type set. This
|
||||
could lead to ignoring a different lock type with the next lock.
|
||||
|
||||
Clear the lock type of all lock data. This ensures that the next
|
||||
lock request will set its lock type properly.
|
||||
|
||||
RETURN
|
||||
void
|
||||
@param sql_lock The MySQL lock.
|
||||
*/
|
||||
|
||||
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
||||
|
|
@ -940,20 +932,19 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
|||
This is used when we need total access to a closed, not open table
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
Lock and wait for the named lock.
|
||||
|
||||
SYNOPSIS
|
||||
lock_and_wait_for_table_name()
|
||||
thd Thread handler
|
||||
table_list Lock first table in this list
|
||||
@param thd Thread handler
|
||||
@param table_list Lock first table in this list
|
||||
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Works together with global read lock.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
|
@ -982,30 +973,30 @@ end:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Put a not open table with an old refresh version in the table cache.
|
||||
|
||||
SYNPOSIS
|
||||
lock_table_name()
|
||||
thd Thread handler
|
||||
table_list Lock first table in this list
|
||||
check_in_use Do we need to check if table already in use by us
|
||||
@param thd Thread handler
|
||||
@param table_list Lock first table in this list
|
||||
@param check_in_use Do we need to check if table already in use by us
|
||||
|
||||
WARNING
|
||||
@note
|
||||
One must have a lock on LOCK_open!
|
||||
|
||||
@warning
|
||||
If you are going to update the table, you should use
|
||||
lock_and_wait_for_table_name instead of this function as this works
|
||||
together with 'FLUSH TABLES WITH READ LOCK'
|
||||
|
||||
NOTES
|
||||
@note
|
||||
This will force any other threads that uses the table to release it
|
||||
as soon as possible.
|
||||
|
||||
REQUIREMENTS
|
||||
One must have a lock on LOCK_open !
|
||||
|
||||
RETURN:
|
||||
@return
|
||||
< 0 error
|
||||
@return
|
||||
== 0 table locked
|
||||
@return
|
||||
> 0 table locked, but someone is using it
|
||||
*/
|
||||
|
||||
|
|
@ -1102,23 +1093,22 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Lock all tables in list with a name lock
|
||||
/**
|
||||
Lock all tables in list with a name lock.
|
||||
|
||||
SYNOPSIS
|
||||
lock_table_names()
|
||||
thd Thread handle
|
||||
table_list Names of tables to lock
|
||||
REQUIREMENTS
|
||||
- One must have a lock on LOCK_open when calling this
|
||||
|
||||
NOTES
|
||||
@param thd Thread handle
|
||||
@param table_list Names of tables to lock
|
||||
|
||||
@note
|
||||
If you are just locking one table, you should use
|
||||
lock_and_wait_for_table_name().
|
||||
|
||||
REQUIREMENTS
|
||||
One must have a lock on LOCK_open when calling this
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 Fatal error (end of memory ?)
|
||||
*/
|
||||
|
||||
|
|
@ -1148,12 +1138,13 @@ end:
|
|||
|
||||
|
||||
/**
|
||||
@brief Lock all tables in list with an exclusive table name lock.
|
||||
Unlock all tables in list with a name lock.
|
||||
|
||||
@param thd Thread handle.
|
||||
@param thd Thread handle.
|
||||
@param table_list Names of tables to lock.
|
||||
|
||||
@note This function needs to be protected by LOCK_open. If we're
|
||||
@note
|
||||
This function needs to be protected by LOCK_open. If we're
|
||||
under LOCK TABLES, this function does not work as advertised. Namely,
|
||||
it does not exclude other threads from using this table and does not
|
||||
put an exclusive name lock on this table into the table cache.
|
||||
|
|
@ -1183,7 +1174,7 @@ bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
|
|||
|
||||
|
||||
/**
|
||||
@brief Test is 'table' is protected by an exclusive name lock.
|
||||
Test is 'table' is protected by an exclusive name lock.
|
||||
|
||||
@param[in] thd The current thread handler
|
||||
@param[in] table_list Table container containing the single table to be
|
||||
|
|
@ -1211,7 +1202,7 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd,
|
|||
|
||||
|
||||
/**
|
||||
@brief Test is 'table key' is protected by an exclusive name lock.
|
||||
Test is 'table key' is protected by an exclusive name lock.
|
||||
|
||||
@param[in] thd The current thread handler.
|
||||
@param[in] key
|
||||
|
|
@ -1245,23 +1236,27 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
Unlock all tables in list with a name lock
|
||||
/**
|
||||
Unlock all tables in list with a name lock.
|
||||
|
||||
SYNOPSIS
|
||||
unlock_table_names()
|
||||
@param
|
||||
thd Thread handle
|
||||
@param
|
||||
table_list Names of tables to unlock
|
||||
@param
|
||||
last_table Don't unlock any tables after this one.
|
||||
(default 0, which will unlock all tables)
|
||||
(default 0, which will unlock all tables)
|
||||
|
||||
NOTES
|
||||
@note
|
||||
One must have a lock on LOCK_open when calling this.
|
||||
|
||||
@note
|
||||
This function will broadcast refresh signals to inform other threads
|
||||
that the name locks are removed.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 Fatal error (end of memory ?)
|
||||
*/
|
||||
|
||||
|
|
@ -1565,14 +1560,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Broadcast COND_refresh and COND_global_read_lock.
|
||||
|
||||
SYNOPSIS
|
||||
broadcast_refresh()
|
||||
void No parameters.
|
||||
|
||||
DESCRIPTION
|
||||
Due to a bug in a threading library it could happen that a signal
|
||||
did not reach its target. A condition for this was that the same
|
||||
condition variable was used with different mutexes in
|
||||
|
|
@ -1584,12 +1574,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
|||
in global read lock handling. But now it is necessary to signal
|
||||
both conditions at the same time.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
When signalling COND_global_read_lock within the global read lock
|
||||
handling, it is not necessary to also signal COND_refresh.
|
||||
|
||||
RETURN
|
||||
void
|
||||
*/
|
||||
|
||||
void broadcast_refresh(void)
|
||||
|
|
|
|||
446
sql/log.cc
446
sql/log.cc
|
|
@ -14,8 +14,15 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/* logging of commands */
|
||||
/* TODO: Abort logging when we get an error in reading or writing log files */
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
logging of commands
|
||||
|
||||
@todo
|
||||
Abort logging when we get an error in reading or writing log files
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "sql_repl.h"
|
||||
|
|
@ -689,7 +696,7 @@ void Log_to_file_event_handler::init_pthread_objects()
|
|||
}
|
||||
|
||||
|
||||
/* Wrapper around MYSQL_LOG::write() for slow log */
|
||||
/** Wrapper around MYSQL_LOG::write() for slow log. */
|
||||
|
||||
bool Log_to_file_event_handler::
|
||||
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
|
||||
|
|
@ -704,7 +711,7 @@ bool Log_to_file_event_handler::
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Wrapper around MYSQL_LOG::write() for general log. We need it since we
|
||||
want all log event handlers to have the same signature.
|
||||
*/
|
||||
|
|
@ -806,7 +813,7 @@ void LOGGER::cleanup_end()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Perform basic log initialization: create file-based log handler and
|
||||
init error log.
|
||||
*/
|
||||
|
|
@ -1458,9 +1465,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE: how do we handle this (unlikely but legal) case:
|
||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
||||
/**
|
||||
@note
|
||||
How do we handle this (unlikely but legal) case:
|
||||
@verbatim
|
||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
||||
@endverbatim
|
||||
The problem occurs when a savepoint is before the update to the
|
||||
non-transactional table. Then when there's a rollback to the savepoint, if we
|
||||
simply truncate the binlog cache, we lose the part of the binlog cache where
|
||||
|
|
@ -1607,11 +1617,14 @@ static void setup_windows_event_source()
|
|||
#endif /* __NT__ */
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Find a uniq filename for 'filename.#'.
|
||||
** Set # to a number as low as possible
|
||||
** returns != 0 if not possible to get uniq filename
|
||||
****************************************************************************/
|
||||
/**
|
||||
Find a unique filename for 'filename.#'.
|
||||
|
||||
Set '#' to a number as low as possible.
|
||||
|
||||
@return
|
||||
nonzero if not possible to get unique filename
|
||||
*/
|
||||
|
||||
static int find_uniq_filename(char *name)
|
||||
{
|
||||
|
|
@ -1825,7 +1838,7 @@ void MYSQL_LOG::close(uint exiting)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/* this is called only once */
|
||||
/** This is called only once. */
|
||||
|
||||
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 *suffix,
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
- Open the log file and the index file. Register the new
|
||||
file name in it
|
||||
file name in it
|
||||
- When calling this when the file is in use, you must have a locks
|
||||
on LOCK_log and LOCK_index.
|
||||
on LOCK_log and LOCK_index.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
|
@ -2428,24 +2446,20 @@ int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Move all data up in a file in an filename index file
|
||||
/**
|
||||
Move all data up in a file in an filename index file.
|
||||
|
||||
SYNOPSIS
|
||||
copy_up_file_and_fill()
|
||||
index_file File to move
|
||||
offset Move everything from here to beginning
|
||||
|
||||
NOTE
|
||||
File will be truncated to be 'offset' shorter or filled up with
|
||||
newlines
|
||||
|
||||
IMPLEMENTATION
|
||||
We do the copy outside of the IO_CACHE as the cache buffers would just
|
||||
make things slower and more complicated.
|
||||
In most cases the copy loop should only do one read.
|
||||
|
||||
RETURN VALUES
|
||||
@param index_file File to move
|
||||
@param offset Move everything from here to beginning
|
||||
|
||||
@note
|
||||
File will be truncated to be 'offset' shorter or filled up with newlines
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
*/
|
||||
|
||||
|
|
@ -2486,25 +2500,25 @@ err:
|
|||
|
||||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
/*
|
||||
Find the position in the log-index-file for the given log name
|
||||
/**
|
||||
Find the position in the log-index-file for the given log name.
|
||||
|
||||
SYNOPSIS
|
||||
find_log_pos()
|
||||
linfo Store here the found log file name and position to
|
||||
the NEXT log file name in the index file.
|
||||
log_name Filename to find in the index file.
|
||||
Is a null pointer if we want to read the first entry
|
||||
need_lock Set this to 1 if the parent doesn't already have a
|
||||
lock on LOCK_index
|
||||
@param linfo Store here the found log file name and position to
|
||||
the NEXT log file name in the index file.
|
||||
@param log_name Filename to find in the index file.
|
||||
Is a null pointer if we want to read the first entry
|
||||
@param need_lock Set this to 1 if the parent doesn't already have a
|
||||
lock on LOCK_index
|
||||
|
||||
NOTE
|
||||
@note
|
||||
On systems without the truncate function the file will end with one or
|
||||
more empty lines. These will be ignored when reading the file.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_IO Got IO error while reading file
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
find_next_log()
|
||||
@param
|
||||
linfo Store here the next log file name and position to
|
||||
the file name after that.
|
||||
@param
|
||||
need_lock Set this to 1 if the parent doesn't already have a
|
||||
lock on LOCK_index
|
||||
|
||||
NOTE
|
||||
@note
|
||||
- Before calling this function, one has to call find_log_pos()
|
||||
to set up 'linfo'
|
||||
to set up 'linfo'
|
||||
- Mutex needed because we need to make sure the file pointer does not move
|
||||
from under our feet
|
||||
from under our feet
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_IO Got IO error while reading file
|
||||
*/
|
||||
|
||||
|
|
@ -2612,21 +2628,20 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Delete all logs refered to in the index file
|
||||
Start writing to a new log file. The new index file will only contain
|
||||
this file.
|
||||
/**
|
||||
Delete all logs refered to in the index file.
|
||||
Start writing to a new log file.
|
||||
|
||||
SYNOPSIS
|
||||
reset_logs()
|
||||
thd Thread
|
||||
The new index file will only contain this file.
|
||||
|
||||
NOTE
|
||||
@param thd Thread
|
||||
|
||||
@note
|
||||
If not called from slave thread, write start event to new log
|
||||
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
|
@ -2690,38 +2705,40 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Delete relay log files prior to rli->group_relay_log_name
|
||||
(i.e. all logs which are not involved in a non-finished group
|
||||
(transaction)), remove them from the index file and start on next relay log.
|
||||
|
||||
SYNOPSIS
|
||||
purge_first_log()
|
||||
rli Relay log information
|
||||
included If false, all relay logs that are strictly before
|
||||
rli->group_relay_log_name are deleted ; if true, the latter is
|
||||
deleted too (i.e. all relay logs
|
||||
read by the SQL slave thread are deleted).
|
||||
|
||||
NOTE
|
||||
- This is only called from the slave-execute thread when it has read
|
||||
all commands from a relay log and want to switch to a new relay log.
|
||||
- When this happens, we can be in an active transaction as
|
||||
a transaction can span over two relay logs
|
||||
(although it is always written as a single block to the master's binary
|
||||
log, hence cannot span over two master's binary logs).
|
||||
(transaction)), remove them from the index file and start on next
|
||||
relay log.
|
||||
|
||||
IMPLEMENTATION
|
||||
- Protects index file with LOCK_index
|
||||
- Delete relevant relay log files
|
||||
- Copy all file names after these ones to the front of the index file
|
||||
- If the OS has truncate, truncate the file, else fill it with \n'
|
||||
- Read the next file name from the index file and store in rli->linfo
|
||||
- Protects index file with LOCK_index
|
||||
- Delete relevant relay log files
|
||||
- Copy all file names after these ones to the front of the index file
|
||||
- If the OS has truncate, truncate the file, else fill it with \n'
|
||||
- Read the next file name from the index file and store in rli->linfo
|
||||
|
||||
RETURN VALUES
|
||||
@param rli Relay log information
|
||||
@param included If false, all relay logs that are strictly before
|
||||
rli->group_relay_log_name are deleted ; if true, the
|
||||
latter is deleted too (i.e. all relay logs
|
||||
read by the SQL slave thread are deleted).
|
||||
|
||||
@note
|
||||
- This is only called from the slave-execute thread when it has read
|
||||
all commands from a relay log and want to switch to a new relay log.
|
||||
- When this happens, we can be in an active transaction as
|
||||
a transaction can span over two relay logs
|
||||
(although it is always written as a single block to the master's binary
|
||||
log, hence cannot span over two master's binary logs).
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_EOF End of log-index-file found
|
||||
@retval
|
||||
LOG_INFO_SEEK Could not allocate IO cache
|
||||
@retval
|
||||
LOG_INFO_IO Got IO error while reading file
|
||||
*/
|
||||
|
||||
|
|
@ -2799,8 +2816,8 @@ err:
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Update log index_file
|
||||
/**
|
||||
Update log index_file.
|
||||
*/
|
||||
|
||||
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
|
||||
|
|
@ -2814,25 +2831,24 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Remove all logs before the given log from disk and from the index file.
|
||||
|
||||
SYNOPSIS
|
||||
purge_logs()
|
||||
to_log Delete all log file name before this file.
|
||||
included If true, to_log is deleted too.
|
||||
need_mutex
|
||||
need_update_threads If we want to update the log coordinates of
|
||||
all threads. False for relay logs, true otherwise.
|
||||
freed_log_space If not null, decrement this variable of
|
||||
the amount of log space freed
|
||||
@param to_log Delete all log file name before this file.
|
||||
@param included If true, to_log is deleted too.
|
||||
@param need_mutex
|
||||
@param need_update_threads If we want to update the log coordinates of
|
||||
all threads. False for relay logs, true otherwise.
|
||||
@param freed_log_space If not null, decrement this variable of
|
||||
the amount of log space freed
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If any of the logs before the deleted one is in use,
|
||||
only purge logs up to this one.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
LOG_INFO_EOF to_log not found
|
||||
*/
|
||||
|
||||
|
|
@ -2916,21 +2932,20 @@ err:
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Remove all logs before the given file date from disk and from the
|
||||
index file.
|
||||
|
||||
SYNOPSIS
|
||||
purge_logs_before_date()
|
||||
thd Thread pointer
|
||||
before_date Delete all log files before given date.
|
||||
@param thd Thread pointer
|
||||
@param before_date Delete all log files before given date.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
If any of the logs before the deleted one is in use,
|
||||
only purge logs up to this one.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
||||
*/
|
||||
|
||||
|
|
@ -2980,14 +2995,12 @@ err:
|
|||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
|
||||
/*
|
||||
Create a new log file name
|
||||
/**
|
||||
Create a new log file name.
|
||||
|
||||
SYNOPSIS
|
||||
make_log_name()
|
||||
buf buf of at least FN_REFLEN where new name is stored
|
||||
@param buf buf of at least FN_REFLEN where new name is stored
|
||||
|
||||
NOTE
|
||||
@note
|
||||
If file name will be longer then FN_REFLEN it will be truncated
|
||||
*/
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
new_file_impl()
|
||||
need_lock Set to 1 if caller has not locked LOCK_log
|
||||
@param need_lock Set to 1 if caller has not locked LOCK_log
|
||||
|
||||
NOTE
|
||||
@note
|
||||
The new file name is stored last in the index file
|
||||
*/
|
||||
|
||||
|
|
@ -3509,8 +3520,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
|
|||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
Write an event to the binary log
|
||||
/**
|
||||
Write an event to the binary log.
|
||||
*/
|
||||
|
||||
bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||
|
|
@ -3949,27 +3960,25 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
|
|||
return 0; // All OK
|
||||
}
|
||||
|
||||
/*
|
||||
Write a cached log entry to the binary log
|
||||
/**
|
||||
Write a cached log entry to the binary log.
|
||||
- To support transaction over replication, we wrap the transaction
|
||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||
We want to write a BEGIN/ROLLBACK block when a non-transactional table
|
||||
was updated in a transaction which was rolled back. This is to ensure
|
||||
that the same updates are run on the slave.
|
||||
|
||||
SYNOPSIS
|
||||
write()
|
||||
thd
|
||||
cache The cache to copy to the binlog
|
||||
commit_event The commit event to print after writing the
|
||||
@param thd
|
||||
@param cache The cache to copy to the binlog
|
||||
@param commit_event The commit event to print after writing the
|
||||
contents of the cache.
|
||||
|
||||
NOTE
|
||||
- We only come here if there is something in the cache.
|
||||
- The thing in the cache is always a complete transaction
|
||||
- 'cache' needs to be reinitialized after this functions returns.
|
||||
|
||||
IMPLEMENTATION
|
||||
- To support transaction over replication, we wrap the transaction
|
||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||
We want to write a BEGIN/ROLLBACK block when a non-transactional table
|
||||
was updated in a transaction which was rolled back. This is to ensure
|
||||
that the same updates are run on the slave.
|
||||
@note
|
||||
We only come here if there is something in the cache.
|
||||
@note
|
||||
The thing in the cache is always a complete transaction.
|
||||
@note
|
||||
'cache' needs to be reinitialized after this functions returns.
|
||||
*/
|
||||
|
||||
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
||||
|
|
@ -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
|
||||
wait_for_update()
|
||||
thd Thread variable
|
||||
is_slave If 0, the caller is the Binlog_dump thread from master;
|
||||
if 1, the caller is the SQL thread from the slave. This
|
||||
influences only thd->proc_info.
|
||||
@param thd Thread variable
|
||||
@param is_slave If 0, the caller is the Binlog_dump thread from master;
|
||||
if 1, the caller is the SQL thread from the slave. This
|
||||
influences only thd->proc_info.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
One must have a lock on LOCK_log before calling this function.
|
||||
This lock will be released before return! That's required by
|
||||
THD::enter_cond() (see NOTES in sql_class.h).
|
||||
|
|
@ -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
|
||||
close()
|
||||
exiting Bitmask for one or more of the following bits:
|
||||
LOG_CLOSE_INDEX if we should close the index file
|
||||
LOG_CLOSE_TO_BE_OPENED if we intend to call open
|
||||
at once after close.
|
||||
LOG_CLOSE_STOP_EVENT write a 'stop' event to the log
|
||||
@param exiting Bitmask for one or more of the following bits:
|
||||
- LOG_CLOSE_INDEX : if we should close the index file
|
||||
- LOG_CLOSE_TO_BE_OPENED : if we intend to call open
|
||||
at once after close.
|
||||
- LOG_CLOSE_STOP_EVENT : write a 'stop' event to the log
|
||||
|
||||
NOTES
|
||||
@note
|
||||
One can do an open on the object at once after doing a close.
|
||||
The internal structures are not freed until cleanup() is called
|
||||
*/
|
||||
|
|
@ -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
|
||||
test_if_number()
|
||||
str String to test
|
||||
res Store value here
|
||||
allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||
@param str String to test
|
||||
@param res Store value here
|
||||
@param allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||
|
||||
NOTE
|
||||
@note
|
||||
For the moment the allow_wildcards argument is not used
|
||||
Should be move to some other file.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 String is a number
|
||||
@retval
|
||||
0 Error
|
||||
*/
|
||||
|
||||
|
|
@ -4345,23 +4349,18 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
|
|||
#endif /* __NT__ */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prints a printf style message to the error log and, under NT, to the
|
||||
Windows event log.
|
||||
|
||||
SYNOPSIS
|
||||
vprint_msg_to_log()
|
||||
event_type Type of event to write (Error, Warning, or Info)
|
||||
format Printf style format of message
|
||||
args va_list list of arguments for the message
|
||||
This function prints the message into a buffer and then sends that buffer
|
||||
to other functions to write that message to other logging sources.
|
||||
|
||||
NOTE
|
||||
@param event_type Type of event to write (Error, Warning, or Info)
|
||||
@param format Printf style format of message
|
||||
@param args va_list list of arguments for the message
|
||||
|
||||
IMPLEMENTATION
|
||||
This function prints the message into a buffer and then sends that buffer
|
||||
to other functions to write that message to other logging sources.
|
||||
|
||||
RETURN VALUES
|
||||
@returns
|
||||
The function always returns 0. The return value is present in the
|
||||
signature to be compatible with other logging routines, which could
|
||||
return an error (e.g. logging to the log tables)
|
||||
|
|
@ -4615,16 +4614,18 @@ err:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
there is no active page, let's got one from the pool
|
||||
/**
|
||||
there is no active page, let's got one from the pool.
|
||||
|
||||
two strategies here:
|
||||
1. take the first from the pool
|
||||
2. if there're waiters - take the one with the most free space
|
||||
Two strategies here:
|
||||
-# take the first from the pool
|
||||
-# if there're waiters - take the one with the most free space.
|
||||
|
||||
TODO page merging. try to allocate adjacent page first,
|
||||
so that they can be flushed both in one sync
|
||||
@todo
|
||||
TODO page merging. try to allocate adjacent page first,
|
||||
so that they can be flushed both in one sync
|
||||
*/
|
||||
|
||||
void TC_LOG_MMAP::get_active_from_pool()
|
||||
{
|
||||
PAGE **p, **best_p=0;
|
||||
|
|
@ -4667,6 +4668,10 @@ void TC_LOG_MMAP::get_active_from_pool()
|
|||
pthread_mutex_unlock(&LOCK_pool);
|
||||
}
|
||||
|
||||
/**
|
||||
@todo
|
||||
perhaps, increase log size ?
|
||||
*/
|
||||
int TC_LOG_MMAP::overflow()
|
||||
{
|
||||
/*
|
||||
|
|
@ -4679,10 +4684,9 @@ int TC_LOG_MMAP::overflow()
|
|||
return 1; // always return 1
|
||||
}
|
||||
|
||||
/*
|
||||
Record that transaction XID is committed on the persistent storage
|
||||
/**
|
||||
Record that transaction XID is committed on the persistent storage.
|
||||
|
||||
NOTES
|
||||
This function is called in the middle of two-phase commit:
|
||||
First all resources prepare the transaction, then tc_log->log() is called,
|
||||
then all resources commit the transaction, then tc_log->unlog() is called.
|
||||
|
|
@ -4693,18 +4697,18 @@ int TC_LOG_MMAP::overflow()
|
|||
threads waiting for a page, but then all these threads will be waiting
|
||||
for a fsync() anyway
|
||||
|
||||
IMPLEMENTATION
|
||||
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
||||
records XID in a special Xid_log_event.
|
||||
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
||||
log.
|
||||
|
||||
RETURN
|
||||
0 Error
|
||||
# "cookie", a number that will be passed as an argument
|
||||
to unlog() call. tc_log can define it any way it wants,
|
||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
||||
to the position in memory where xid was logged to.
|
||||
@retval
|
||||
0 - error
|
||||
@retval
|
||||
\# - otherwise, "cookie", a number that will be passed as an argument
|
||||
to unlog() call. tc_log can define it any way it wants,
|
||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
||||
to the position in memory where xid was logged to.
|
||||
*/
|
||||
|
||||
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
|
||||
|
|
@ -4812,9 +4816,9 @@ int TC_LOG_MMAP::sync()
|
|||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
erase xid from the page, update page free space counters/pointers.
|
||||
cookie points directly to the memory where xid was logged
|
||||
cookie points directly to the memory where xid was logged.
|
||||
*/
|
||||
|
||||
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
|
||||
|
|
@ -4925,16 +4929,17 @@ TC_LOG *tc_log;
|
|||
TC_LOG_DUMMY tc_log_dummy;
|
||||
TC_LOG_MMAP tc_log_mmap;
|
||||
|
||||
/*
|
||||
Perform heuristic recovery, if --tc-heuristic-recover was used
|
||||
/**
|
||||
Perform heuristic recovery, if --tc-heuristic-recover was used.
|
||||
|
||||
RETURN VALUE
|
||||
0 no heuristic recovery was requested
|
||||
1 heuristic recovery was performed
|
||||
|
||||
NOTE
|
||||
@note
|
||||
no matter whether heuristic recovery was successful or not
|
||||
mysqld must exit. So, return value is the same in both cases.
|
||||
|
||||
@retval
|
||||
0 no heuristic recovery was requested
|
||||
@retval
|
||||
1 heuristic recovery was performed
|
||||
*/
|
||||
|
||||
int TC_LOG::using_heuristic_recover()
|
||||
|
|
@ -4952,8 +4957,9 @@ int TC_LOG::using_heuristic_recover()
|
|||
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
||||
#define TC_LOG_BINLOG MYSQL_BIN_LOG
|
||||
|
||||
/*
|
||||
TODO keep in-memory list of prepared transactions
|
||||
/**
|
||||
@todo
|
||||
keep in-memory list of prepared transactions
|
||||
(add to list in log(), remove on unlog())
|
||||
and copy it to the new binlog if rotated
|
||||
but let's check the behaviour of tc_log_page_waits first!
|
||||
|
|
@ -5044,7 +5050,7 @@ err:
|
|||
return error;
|
||||
}
|
||||
|
||||
/* this is called on shutdown, after ha_panic */
|
||||
/** This is called on shutdown, after ha_panic. */
|
||||
void TC_LOG_BINLOG::close()
|
||||
{
|
||||
DBUG_ASSERT(prepared_xids==0);
|
||||
|
|
@ -5052,12 +5058,14 @@ void TC_LOG_BINLOG::close()
|
|||
pthread_cond_destroy (&COND_prep_xids);
|
||||
}
|
||||
|
||||
/*
|
||||
TODO group commit
|
||||
/**
|
||||
@todo
|
||||
group commit
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
1 - success
|
||||
@retval
|
||||
0 error
|
||||
@retval
|
||||
1 success
|
||||
*/
|
||||
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
||||
{
|
||||
|
|
|
|||
297
sql/log_event.cc
297
sql/log_event.cc
|
|
@ -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)
|
||||
|
|
@ -273,21 +273,20 @@ static char *pretty_print_str(char *packet, char *str, int len)
|
|||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
Creates a temporary name for load data infile:
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
SYNOPSIS
|
||||
slave_load_file_stem()
|
||||
buf Store new filename here
|
||||
file_id File_id (part of file name)
|
||||
event_server_id Event_id (part of file name)
|
||||
ext Extension for file name
|
||||
/**
|
||||
Creates a temporary name for load data infile:.
|
||||
|
||||
RETURN
|
||||
@param buf Store new filename here
|
||||
@param file_id File_id (part of file name)
|
||||
@param event_server_id Event_id (part of file name)
|
||||
@param ext Extension for file name
|
||||
|
||||
@return
|
||||
Pointer to start of extension
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
static char *slave_load_file_stem(char *buf, uint file_id,
|
||||
int event_server_id, const char *ext)
|
||||
{
|
||||
|
|
@ -307,14 +306,12 @@ static char *slave_load_file_stem(char *buf, uint file_id,
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Delete all temporary files used for SQL_LOAD.
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
SYNOPSIS
|
||||
cleanup_load_tmpdir()
|
||||
/**
|
||||
Delete all temporary files used for SQL_LOAD.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
static void cleanup_load_tmpdir()
|
||||
{
|
||||
MY_DIR *dirp;
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
|
|
@ -399,12 +396,14 @@ char *str_to_hex(char *to, const char *from, uint len)
|
|||
return to; // pointer to end 0 of 'to'
|
||||
}
|
||||
|
||||
/*
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/**
|
||||
Append a version of the 'from' string suitable for use in a query to
|
||||
the 'to' string. To generate a correct escaping, the character set
|
||||
information in 'csinfo' is used.
|
||||
*/
|
||||
#ifndef MYSQL_CLIENT
|
||||
*/
|
||||
|
||||
int
|
||||
append_query_string(CHARSET_INFO *csinfo,
|
||||
String const *from, String *to)
|
||||
|
|
@ -431,7 +430,7 @@ append_query_string(CHARSET_INFO *csinfo,
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
||||
commands just before it prints a query.
|
||||
*/
|
||||
|
|
@ -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::get_type_str()
|
||||
/**
|
||||
@return
|
||||
returns the human readable name of the event's type
|
||||
*/
|
||||
|
||||
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
|
||||
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
|
||||
|
|
@ -675,12 +675,9 @@ void Log_event::pack_info(Protocol *protocol)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Log_event::net_send()
|
||||
|
||||
/**
|
||||
Only called by SHOW BINLOG EVENTS
|
||||
*/
|
||||
|
||||
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
||||
{
|
||||
const char *p= strrchr(log_name, FN_LIBCHAR);
|
||||
|
|
@ -701,8 +698,10 @@ int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
|||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
|
||||
/*
|
||||
Log_event::init_show_field_list()
|
||||
/**
|
||||
init_show_field_list() prepares the column names and types for the
|
||||
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
|
||||
EVENTS.
|
||||
*/
|
||||
|
||||
void Log_event::init_show_field_list(List<Item>* field_list)
|
||||
|
|
@ -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
|
||||
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,
|
||||
|
|
@ -886,14 +882,11 @@ end:
|
|||
#define LOCK_MUTEX
|
||||
#endif
|
||||
|
||||
/*
|
||||
Log_event::read_log_event()
|
||||
|
||||
NOTE:
|
||||
#ifndef MYSQL_CLIENT
|
||||
/**
|
||||
@note
|
||||
Allocates memory; The caller is responsible for clean-up.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
pthread_mutex_t* log_lock,
|
||||
const Format_description_log_event
|
||||
|
|
@ -991,8 +984,7 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Log_event::read_log_event()
|
||||
/**
|
||||
Binlog format tolerance is in (buf, event_len, description_event)
|
||||
constructors.
|
||||
*/
|
||||
|
|
@ -1329,12 +1321,13 @@ Log_event::continue_group(Relay_log_info *rli)
|
|||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
/*
|
||||
Query_log_event::pack_info()
|
||||
/**
|
||||
This (which is used only for SHOW BINLOG EVENTS) could be updated to
|
||||
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
|
||||
only an information, it does not produce suitable queries to replay (for
|
||||
example it does not print LOAD DATA INFILE).
|
||||
@todo
|
||||
show the catalog ??
|
||||
*/
|
||||
|
||||
void Query_log_event::pack_info(Protocol *protocol)
|
||||
|
|
@ -1363,7 +1356,9 @@ void Query_log_event::pack_info(Protocol *protocol)
|
|||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/* Utility function for the next method */
|
||||
/**
|
||||
Utility function for the next method (Query_log_event::write()) .
|
||||
*/
|
||||
static void write_str_with_code_and_len(char **dst, const char *src,
|
||||
int len, uint code)
|
||||
{
|
||||
|
|
@ -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
|
||||
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
Query_log_event::Query_log_event()
|
||||
|
||||
/**
|
||||
The simplest constructor that could possibly work. This is used for
|
||||
creating static objects that have a special meaning and are invisible
|
||||
to the log.
|
||||
|
|
@ -1755,11 +1748,10 @@ code_name(int code)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
Query_log_event::Query_log_event()
|
||||
|
||||
/**
|
||||
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,
|
||||
const Format_description_log_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
|
||||
/**
|
||||
Query_log_event::print().
|
||||
|
||||
@todo
|
||||
print the catalog ??
|
||||
*/
|
||||
void Query_log_event::print_query_header(IO_CACHE* file,
|
||||
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,
|
||||
const char *query_arg, uint32 q_len_arg)
|
||||
{
|
||||
|
|
@ -2612,30 +2623,31 @@ bool Start_log_event_v3::write(IO_CACHE* file)
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Start_log_event_v3::do_apply_event()
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
/**
|
||||
Start_log_event_v3::do_apply_event() .
|
||||
The master started
|
||||
|
||||
IMPLEMENTATION
|
||||
IMPLEMENTATION
|
||||
- To handle the case where the master died without having time to write
|
||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
||||
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||
can (see below).
|
||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
||||
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||
can (see below).
|
||||
|
||||
TODO
|
||||
@todo
|
||||
- Remove all active user locks.
|
||||
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
||||
the use of a bit of memory for a user lock which will not be used
|
||||
anymore. If the user lock is later used, the old one will be released. In
|
||||
other words, no deadlock problem.
|
||||
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
||||
the use of a bit of memory for a user lock which will not be used
|
||||
anymore. If the user lock is later used, the old one will be released. In
|
||||
other words, no deadlock problem.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
||||
{
|
||||
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
||||
switch (binlog_version) {
|
||||
switch (binlog_version)
|
||||
{
|
||||
case 3:
|
||||
case 4:
|
||||
/*
|
||||
|
|
@ -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 1st ctor.
|
||||
|
||||
SYNOPSIS
|
||||
Format_description_log_event::Format_description_log_event
|
||||
binlog_version the binlog version for which we want to build
|
||||
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
|
||||
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
|
||||
old 4.0 (binlog version 2) is not supported;
|
||||
it should not be used for replication with
|
||||
5.0.
|
||||
|
||||
DESCRIPTION
|
||||
Ctor. Can be used to create the event to write to the binary log (when the
|
||||
server starts or when FLUSH LOGS), or to create artificial events to parse
|
||||
binlogs from MySQL 3.23 or 4.x.
|
||||
When in a client, only the 2nd use is possible.
|
||||
|
||||
@param binlog_version the binlog version for which we want to build
|
||||
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
|
||||
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
|
||||
old 4.0 (binlog version 2) is not supported;
|
||||
it should not be used for replication with
|
||||
5.0.
|
||||
*/
|
||||
|
||||
Format_description_log_event::
|
||||
|
|
@ -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
|
||||
length different from this version, but we don't know this length as we
|
||||
have not read the Format_description_log_event which says it, yet. This
|
||||
length is in the post-header of the event, but we don't know where the
|
||||
post-header starts.
|
||||
|
||||
So this type of event HAS to:
|
||||
- either have the header's length at the beginning (in the header, at a
|
||||
fixed position which will never be changed), not in the post-header. That
|
||||
would make the header be "shifted" compared to other events.
|
||||
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
|
||||
versions, so that we know for sure.
|
||||
|
||||
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
||||
it is sent before Format_description_log_event).
|
||||
*/
|
||||
|
|
@ -3253,14 +3264,11 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
|||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
Load_log_event::Load_log_event()
|
||||
|
||||
NOTE
|
||||
/**
|
||||
@note
|
||||
The caller must do buf[event_len] = 0 before he starts using the
|
||||
constructed event.
|
||||
*/
|
||||
|
||||
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
||||
const Format_description_log_event *description_event)
|
||||
:Log_event(buf, description_event), num_fields(0), fields(0),
|
||||
|
|
@ -3435,17 +3443,18 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
|
|||
}
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
/**
|
||||
Load_log_event::set_fields()
|
||||
|
||||
Note that this function can not use the member variable
|
||||
for the database, since LOAD DATA INFILE on the slave
|
||||
can be for a different database than the current one.
|
||||
This is the reason for the affected_db argument to this method.
|
||||
@note
|
||||
This function can not use the member variable
|
||||
for the database, since LOAD DATA INFILE on the slave
|
||||
can be for a different database than the current one.
|
||||
This is the reason for the affected_db argument to this method.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
void Load_log_event::set_fields(const char* affected_db,
|
||||
List<Item> &field_list,
|
||||
Name_resolution_context *context)
|
||||
|
|
@ -3463,32 +3472,33 @@ void Load_log_event::set_fields(const char* affected_db,
|
|||
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
/*
|
||||
Does the data loading job when executing a LOAD DATA on the slave
|
||||
/**
|
||||
Does the data loading job when executing a LOAD DATA on the slave.
|
||||
|
||||
SYNOPSIS
|
||||
Load_log_event::do_apply_event
|
||||
net
|
||||
rli
|
||||
use_rli_only_for_errors - if set to 1, rli is provided to
|
||||
Load_log_event::do_apply_event
|
||||
only for this function to have
|
||||
RPL_LOG_NAME and
|
||||
rli->last_slave_error, both being
|
||||
used by error reports. rli's
|
||||
position advancing is skipped (done
|
||||
by the caller which is
|
||||
Execute_load_log_event::do_apply_event).
|
||||
- if set to 0, rli is provided for
|
||||
full use, i.e. for error reports and
|
||||
position advancing.
|
||||
@param net
|
||||
@param rli
|
||||
@param use_rli_only_for_errors If set to 1, rli is provided to
|
||||
Load_log_event::exec_event only for this
|
||||
function to have RPL_LOG_NAME and
|
||||
rli->last_slave_error, both being used by
|
||||
error reports. rli's position advancing
|
||||
is skipped (done by the caller which is
|
||||
Execute_load_log_event::exec_event).
|
||||
If set to 0, rli is provided for full use,
|
||||
i.e. for error reports and position
|
||||
advancing.
|
||||
|
||||
DESCRIPTION
|
||||
Does the data loading job when executing a LOAD DATA on the slave
|
||||
@todo
|
||||
fix this; this can be done by testing rules in
|
||||
Create_file_log_event::exec_event() and then discarding Append_block and
|
||||
al.
|
||||
@todo
|
||||
this is a bug - this needs to be moved to the I/O thread
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 Success
|
||||
1 Failure
|
||||
@retval
|
||||
1 Failure
|
||||
*/
|
||||
|
||||
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
||||
|
|
@ -3864,24 +3874,21 @@ bool Rotate_log_event::write(IO_CACHE* file)
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
|
||||
/*
|
||||
Rotate_log_event::do_apply_event()
|
||||
Got a rotate log event from the master.
|
||||
|
||||
Got a rotate log event from the master
|
||||
This is mainly used so that we can later figure out the logname and
|
||||
position for the master.
|
||||
|
||||
IMPLEMENTATION
|
||||
This is mainly used so that we can later figure out the logname and
|
||||
position for the master.
|
||||
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||
in a A -> B -> A setup.
|
||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
||||
|
||||
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||
in a A -> B -> A setup.
|
||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
*/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
||||
{
|
||||
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
||||
|
|
@ -4233,12 +4240,12 @@ void Xid_log_event::pack_info(Protocol *protocol)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
NOTE it's ok not to use int8store here,
|
||||
/**
|
||||
@note
|
||||
It's ok not to use int8store here,
|
||||
as long as xid_t::set(ulonglong) and
|
||||
xid_t::get_my_xid doesn't do it either
|
||||
|
||||
we don't care about actual values of xids as long as
|
||||
xid_t::get_my_xid doesn't do it either.
|
||||
We don't care about actual values of xids as long as
|
||||
identical numbers compare identically
|
||||
*/
|
||||
|
||||
|
|
@ -4717,6 +4724,10 @@ void Slave_log_event::pack_info(Protocol *protocol)
|
|||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/**
|
||||
@todo
|
||||
re-write this better without holding both locks at the same time
|
||||
*/
|
||||
Slave_log_event::Slave_log_event(THD* thd_arg,
|
||||
Relay_log_info* rli)
|
||||
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
|
||||
|
|
@ -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)
|
||||
: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 */
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/*
|
||||
Stop_log_event::do_apply_event()
|
||||
|
||||
The master stopped. We used to clean up all temporary tables but
|
||||
this is useless as, as the master has shut down properly, it has
|
||||
written all DROP TEMPORARY TABLE (prepared statements' deletion is
|
||||
|
|
@ -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
|
||||
here, the master was sane.
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Prints the query as LOAD DATA LOCAL and with rewritten filename.
|
||||
*/
|
||||
void Execute_load_query_log_event::print(FILE* file,
|
||||
PRINT_EVENT_INFO* print_event_info,
|
||||
const char *local_fname)
|
||||
|
|
@ -6755,15 +6765,17 @@ void Rows_log_event::print_helper(FILE *file,
|
|||
type used is uint32.
|
||||
*/
|
||||
|
||||
#if !defined(MYSQL_CLIENT)
|
||||
/**
|
||||
Save the field metadata based on the real_type of the field.
|
||||
The metadata saved depends on the type of the field. Some fields
|
||||
store a single byte for pack_length() while others store two bytes
|
||||
for field_length (max length).
|
||||
|
||||
@retval 0 Ok.
|
||||
@retval 0 Ok.
|
||||
|
||||
TODO: We may want to consider changing the encoding of the information.
|
||||
@todo
|
||||
We may want to consider changing the encoding of the information.
|
||||
Currently, the code attempts to minimize the number of bytes written to
|
||||
the tablemap. There are at least two other alternatives; 1) using
|
||||
net_store_length() to store the data allowing it to choose the number of
|
||||
|
|
@ -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
|
||||
not encode 2 parts.
|
||||
*/
|
||||
#if !defined(MYSQL_CLIENT)
|
||||
int Table_map_log_event::save_field_metadata()
|
||||
{
|
||||
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
Cashing of files with only does (sequential) read or writes of fixed-
|
||||
/**
|
||||
@file
|
||||
|
||||
@details
|
||||
Caching of files with only does (sequential) read or writes of fixed-
|
||||
length records. A read isn't allowed to go over file-length. A read is ok
|
||||
if it ends at file-length and next read can try to read after file-length
|
||||
(and get a EOF-error).
|
||||
|
|
@ -34,11 +37,15 @@
|
|||
|
||||
extern "C" {
|
||||
|
||||
/*
|
||||
** Read buffered from the net.
|
||||
** Returns 1 if can't read requested characters
|
||||
** Returns 0 if record read
|
||||
*/
|
||||
/**
|
||||
Read buffered from the net.
|
||||
|
||||
@retval
|
||||
1 if can't read requested characters
|
||||
@retval
|
||||
0 if record read
|
||||
*/
|
||||
|
||||
|
||||
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
||||
size_t Count __attribute__((unused)))
|
||||
|
|
|
|||
|
|
@ -18,17 +18,15 @@
|
|||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
/*
|
||||
report result of decimal operation
|
||||
/**
|
||||
report result of decimal operation.
|
||||
|
||||
SYNOPSIS
|
||||
decimal_operation_results()
|
||||
result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
@param result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
|
||||
TODO
|
||||
@todo
|
||||
Fix error messages
|
||||
|
||||
RETURN
|
||||
@return
|
||||
result
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,9 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
It is interface module to fixed precision decimals library.
|
||||
|
||||
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_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
|
||||
|
||||
/* the number of digits that my_decimal can possibly contain */
|
||||
#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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 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_NOT_SPECIFIED 31
|
||||
|
||||
/*
|
||||
/**
|
||||
maximum length of string representation (number of maximum decimal
|
||||
digits + 1 position for sign + 1 position for decimal point)
|
||||
*/
|
||||
#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
|
||||
|
||||
|
|
@ -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
|
||||
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
|
||||
|
|
@ -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
|
||||
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -13,10 +13,13 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
@details
|
||||
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).
|
||||
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.
|
||||
*/
|
||||
|
||||
|
|
@ -253,12 +256,12 @@ protected:
|
|||
Feel free to raise this by the smallest amount you can to get the
|
||||
"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_BUFF_ALLOC 352 // For stack overrun checks
|
||||
#define STACK_BUFF_ALLOC 352 ///< For stack overrun checks
|
||||
#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
|
||||
#define TEMP_POOL_SIZE 128
|
||||
|
||||
|
|
@ -282,14 +285,14 @@ protected:
|
|||
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
|
||||
#define MIN_ROWS_TO_USE_BULK_INSERT 100
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
WHERE clause is comparable to reading one extra row from a table.
|
||||
*/
|
||||
#define TIME_FOR_COMPARE 5 // 5 compares == one read
|
||||
|
||||
/*
|
||||
/**
|
||||
Number of comparisons of table rowids equivalent to reading one row from a
|
||||
table.
|
||||
*/
|
||||
|
|
@ -309,17 +312,17 @@ protected:
|
|||
#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.
|
||||
This value is only used when we don't know anything about the key
|
||||
distribution.
|
||||
*/
|
||||
#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
|
||||
|
||||
/* Characters shown for the command in 'show processlist' */
|
||||
/** Characters shown for the command in 'show processlist'. */
|
||||
#define PROCESS_LIST_WIDTH 100
|
||||
/* Characters shown for the command in 'information_schema.processlist' */
|
||||
#define PROCESS_LIST_INFO_WIDTH 65535
|
||||
|
|
@ -335,11 +338,11 @@ protected:
|
|||
|
||||
/* The following can also be changed from the command line */
|
||||
#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_WAIT_TIMEOUT 5*60 /* Wait for delayed insert */
|
||||
#define FLUSH_TIME 0 /* Don't flush tables */
|
||||
#define MAX_CONNECT_ERRORS 10 // errors before disabling host
|
||||
#define DELAYED_WAIT_TIMEOUT 5*60 /**< Wait for delayed insert */
|
||||
#define FLUSH_TIME 0 /**< Don't flush tables */
|
||||
#define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
|
||||
|
||||
#ifdef __NETWARE__
|
||||
#define IF_NETWARE(A,B) A
|
||||
|
|
@ -349,7 +352,7 @@ protected:
|
|||
|
||||
#if defined(__WIN__)
|
||||
#undef FLUSH_TIME
|
||||
#define FLUSH_TIME 1800 /* Flush every half hour */
|
||||
#define FLUSH_TIME 1800 /**< Flush every half hour */
|
||||
|
||||
#define INTERRUPT_PRIOR -2
|
||||
#define CONNECT_PRIOR -1
|
||||
|
|
@ -368,12 +371,12 @@ protected:
|
|||
#define TEST_MIT_THREAD 4
|
||||
#define TEST_BLOCKING 8
|
||||
#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_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_SIGINT 1024 /* Allow sigint on threads */
|
||||
#define TEST_SYNCHRONIZATION 2048 /* get server to do sleep in
|
||||
#define TEST_SIGINT 1024 /**< Allow sigint on threads */
|
||||
#define TEST_SYNCHRONIZATION 2048 /**< get server to do sleep in
|
||||
some places */
|
||||
#endif
|
||||
|
||||
|
|
@ -423,26 +426,26 @@ protected:
|
|||
/* The following is used to detect a conflict with DISTINCT */
|
||||
#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 */
|
||||
#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 */
|
||||
#define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog
|
||||
#define SELECT_NO_UNLOCK (ULL(1) << 28) // 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
|
||||
/* 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
|
||||
/*
|
||||
/**
|
||||
Force the used temporary table to be a MyISAM table (because we will use
|
||||
fulltext functions when reading from it.
|
||||
*/
|
||||
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Maximum length of time zone name that we support
|
||||
(Time zone name is char(64) in db). mysqlbinlog needs it.
|
||||
*/
|
||||
|
|
@ -505,9 +508,9 @@ protected:
|
|||
#define UNCACHEABLE_DEPENDENT 1
|
||||
#define UNCACHEABLE_RAND 2
|
||||
#define UNCACHEABLE_SIDEEFFECT 4
|
||||
// forcing to save JOIN for explain
|
||||
/// forcing to save JOIN for explain
|
||||
#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
|
||||
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
|
||||
#define UNCACHEABLE_UNITED 32
|
||||
|
|
@ -515,7 +518,7 @@ protected:
|
|||
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
|
||||
#define UNDEF_POS (-1)
|
||||
#ifdef EXTRA_DEBUG
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
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 tmp_file_prefix "#sql" /* Prefix for tmp tables */
|
||||
#define tmp_file_prefix "#sql" /**< Prefix for tmp tables */
|
||||
#define tmp_file_prefix_length 4
|
||||
|
||||
/* Flags for calc_week() function. */
|
||||
|
|
@ -586,9 +589,9 @@ enum enum_check_fields
|
|||
CHECK_FIELD_WARN,
|
||||
CHECK_FIELD_ERROR_FOR_NULL
|
||||
};
|
||||
|
||||
/* Struct to handle simple linked lists */
|
||||
|
||||
|
||||
/** Struct to handle simple linked lists. */
|
||||
typedef struct st_sql_list {
|
||||
uint elements;
|
||||
uchar *first;
|
||||
|
|
@ -2209,16 +2212,15 @@ Item * all_any_subquery_creator(Item *left_expr,
|
|||
bool all,
|
||||
SELECT_LEX *select_lex);
|
||||
|
||||
/*
|
||||
clean/setup table fields and map
|
||||
/**
|
||||
clean/setup table fields and map.
|
||||
|
||||
SYNOPSYS
|
||||
setup_table_map()
|
||||
table - TABLE structure pointer (which should be setup)
|
||||
table_list TABLE_LIST structure pointer (owner of TABLE)
|
||||
tablenr - table number
|
||||
@param table TABLE structure pointer (which should be setup)
|
||||
@param table_list TABLE_LIST structure pointer (owner of TABLE)
|
||||
@param tablenr table number
|
||||
*/
|
||||
|
||||
|
||||
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
||||
{
|
||||
table->used_fields= 0;
|
||||
|
|
@ -2240,10 +2242,8 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSYS
|
||||
hexchar_to_int()
|
||||
convert a hex digit into number
|
||||
/**
|
||||
convert a hex digit into number.
|
||||
*/
|
||||
|
||||
inline int hexchar_to_int(char c)
|
||||
|
|
@ -2256,11 +2256,9 @@ inline int hexchar_to_int(char c)
|
|||
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)
|
||||
{
|
||||
const char *name= table->s->table_name.str;
|
||||
|
|
|
|||
248
sql/mysqld.cc
248
sql/mysqld.cc
|
|
@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
|
|||
typedef fp_except fp_except_t;
|
||||
#endif
|
||||
|
||||
/* We can't handle floating point exceptions with threads, so disable
|
||||
this on freebsd
|
||||
*/
|
||||
|
||||
/**
|
||||
We can't handle floating point exceptions with threads, so disable
|
||||
this on freebsd.
|
||||
*/
|
||||
inline void reset_floating_point_exceptions()
|
||||
{
|
||||
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
|
||||
|
|
@ -325,7 +325,7 @@ static my_bool opt_short_log_format= 0;
|
|||
static uint kill_cached_threads, wake_thread;
|
||||
static ulong killed_threads, thread_created;
|
||||
static ulong max_used_connections;
|
||||
static ulong my_bind_addr; /* the address we bind to */
|
||||
static ulong my_bind_addr; /**< the address we bind to */
|
||||
static volatile ulong cached_thread_count= 0;
|
||||
static const char *sql_mode_str= "OFF";
|
||||
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
||||
|
|
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
|
|||
*/
|
||||
bool volatile grant_option;
|
||||
|
||||
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted
|
||||
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
|
||||
my_bool opt_reckless_slave = 0;
|
||||
my_bool opt_enable_named_pipe= 0;
|
||||
my_bool opt_local_infile, opt_slave_compressed_protocol;
|
||||
|
|
@ -430,7 +430,7 @@ TYPELIB binlog_format_typelib=
|
|||
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
|
||||
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
||||
#ifdef HAVE_INITGROUPS
|
||||
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
|
||||
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
|
||||
#endif
|
||||
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
||||
uint mysqld_port_timeout;
|
||||
|
|
@ -458,12 +458,12 @@ ulong specialflag=0;
|
|||
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
||||
ulong max_connections, max_connect_errors;
|
||||
uint max_user_connections= 0;
|
||||
/*
|
||||
/**
|
||||
Limit of the total number of prepared statements in the server.
|
||||
Is necessary to protect the server against out-of-memory attacks.
|
||||
*/
|
||||
ulong max_prepared_stmt_count;
|
||||
/*
|
||||
/**
|
||||
Current total number of prepared statements in the server. This number
|
||||
is exact, and therefore may not be equal to the difference between
|
||||
`com_stmt_prepare' and `com_stmt_close' (global status variables), as
|
||||
|
|
@ -499,13 +499,13 @@ uint mysql_data_home_len;
|
|||
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
|
||||
char server_version[SERVER_VERSION_LENGTH];
|
||||
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
||||
const char **errmesg; /* Error messages */
|
||||
const char **errmesg; /**< Error messages */
|
||||
const char *myisam_recover_options_str="OFF";
|
||||
const char *myisam_stats_method_str="nulls_unequal";
|
||||
|
||||
/* name of reference on left espression in rewritten IN subquery */
|
||||
/** name of reference on left espression in rewritten IN subquery */
|
||||
const char *in_left_expr_name= "<left expr>";
|
||||
/* name of additional condition */
|
||||
/** name of additional condition */
|
||||
const char *in_additional_cond= "<IN COND>";
|
||||
const char *in_having_cond= "<IN HAVING>";
|
||||
|
||||
|
|
@ -555,7 +555,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
|||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||
LOCK_global_system_variables,
|
||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||
/*
|
||||
/**
|
||||
The below lock protects access to two global server variables:
|
||||
max_prepared_stmt_count and prepared_stmt_count. These variables
|
||||
set the limit and hold the current total number of prepared statements
|
||||
|
|
@ -604,7 +604,7 @@ static char **defaults_argv;
|
|||
static char *opt_bin_logname;
|
||||
|
||||
static my_socket unix_sock,ip_sock;
|
||||
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
|
||||
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
struct passwd *user_info;
|
||||
|
|
@ -628,7 +628,7 @@ static char **opt_argv;
|
|||
static HANDLE hEventShutdown;
|
||||
static char shutdown_event_name[40];
|
||||
#include "nt_servc.h"
|
||||
static NTService Service; // Service object for WinNT
|
||||
static NTService Service; ///< Service object for WinNT
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
#endif /* __WIN__ */
|
||||
|
||||
|
|
@ -1009,19 +1009,15 @@ void kill_mysql(void)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Force server down. Kill all connections and threads and exit
|
||||
/**
|
||||
Force server down. Kill all connections and threads and exit.
|
||||
|
||||
SYNOPSIS
|
||||
kill_server
|
||||
@param sig_ptr Signal number that caused kill_server to be called.
|
||||
|
||||
sig_ptr Signal number that caused kill_server to be called.
|
||||
|
||||
NOTE!
|
||||
@note
|
||||
A signal number of 0 mean that the function was not called
|
||||
from a signal handler and there is thus no signal to block
|
||||
or stop, we just want to kill the server.
|
||||
|
||||
*/
|
||||
|
||||
#if defined(__NETWARE__)
|
||||
|
|
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
cleanup all memory and end program nicely
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
SYNOPSIS
|
||||
unireg_end()
|
||||
|
||||
NOTES
|
||||
This function never returns.
|
||||
/**
|
||||
cleanup all memory and end program nicely.
|
||||
|
||||
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
||||
by the main thread. To get MySQL to shut down nicely in this case
|
||||
(Mac OS X) we have to call exit() instead if pthread_exit().
|
||||
*/
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
@note
|
||||
This function never returns.
|
||||
*/
|
||||
void unireg_end(void)
|
||||
{
|
||||
clean_up(1);
|
||||
|
|
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
|
|||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
/*
|
||||
/**
|
||||
This is mainly needed when running with purify, but it's still nice to
|
||||
know that all child threads have died when mysqld exits
|
||||
know that all child threads have died when mysqld exits.
|
||||
*/
|
||||
|
||||
static void wait_for_signal_thread_to_end()
|
||||
{
|
||||
#ifndef __NETWARE__
|
||||
|
|
@ -1506,8 +1498,7 @@ static void set_effective_user(struct passwd *user_info_arg)
|
|||
}
|
||||
|
||||
|
||||
/* Change root user if started with --chroot */
|
||||
|
||||
/** Change root user if started with @c --chroot . */
|
||||
static void set_root(const char *path)
|
||||
{
|
||||
#if !defined(__WIN__) && !defined(__NETWARE__)
|
||||
|
|
@ -1696,19 +1687,16 @@ static void network_init(void)
|
|||
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/*
|
||||
Close a connection
|
||||
/**
|
||||
Close a connection.
|
||||
|
||||
SYNOPSIS
|
||||
close_connection()
|
||||
thd Thread handle
|
||||
errcode Error code to print to console
|
||||
lock 1 if we have have to lock LOCK_thread_count
|
||||
@param thd Thread handle
|
||||
@param errcode Error code to print to console
|
||||
@param lock 1 if we have have to lock LOCK_thread_count
|
||||
|
||||
NOTES
|
||||
@note
|
||||
For the connection that is doing shutdown, this is called twice
|
||||
*/
|
||||
|
||||
void close_connection(THD *thd, uint errcode, bool lock)
|
||||
{
|
||||
st_vio *vio;
|
||||
|
|
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
|
|||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/* Called when a thread is aborted */
|
||||
/* ARGSUSED */
|
||||
|
||||
/** Called when a thread is aborted. */
|
||||
/* ARGSUSED */
|
||||
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
|
|
@ -1877,13 +1864,13 @@ void flush_thread_cache()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Aborts a thread nicely. Commes here on SIGPIPE
|
||||
TODO: One should have to fix that thr_alarm know about this
|
||||
thread too.
|
||||
*/
|
||||
|
||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||
/**
|
||||
Aborts a thread nicely. Comes here on SIGPIPE.
|
||||
|
||||
@todo
|
||||
One should have to fix that thr_alarm know about this thread too.
|
||||
*/
|
||||
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
||||
{
|
||||
THD *thd=current_thd;
|
||||
|
|
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
|
|||
|
||||
#elif defined(__NETWARE__)
|
||||
|
||||
// down server event callback
|
||||
/// down server event callback.
|
||||
void mysql_down_server_cb(void *, void *)
|
||||
{
|
||||
event_flag= TRUE;
|
||||
|
|
@ -1939,7 +1926,7 @@ void mysql_down_server_cb(void *, void *)
|
|||
}
|
||||
|
||||
|
||||
// destroy callback resources
|
||||
/// destroy callback resources.
|
||||
void mysql_cb_destroy(void *)
|
||||
{
|
||||
UnRegisterEventNotification(eh); // cleanup down event notification
|
||||
|
|
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
|
|||
}
|
||||
|
||||
|
||||
// initialize callbacks
|
||||
/// initialize callbacks.
|
||||
void mysql_cb_init()
|
||||
{
|
||||
// register for down server event
|
||||
|
|
@ -1974,8 +1961,7 @@ void mysql_cb_init()
|
|||
}
|
||||
|
||||
|
||||
/* To get the name of the NetWare volume having MySQL data folder */
|
||||
|
||||
/** To get the name of the NetWare volume having MySQL data folder. */
|
||||
static void getvolumename()
|
||||
{
|
||||
char *p;
|
||||
|
|
@ -1989,8 +1975,8 @@ static void getvolumename()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Registering with NEB for NSS Volume Deactivation event
|
||||
/**
|
||||
Registering with NEB for NSS Volume Deactivation event.
|
||||
*/
|
||||
|
||||
static void registerwithneb()
|
||||
|
|
@ -2042,8 +2028,8 @@ static void registerwithneb()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Callback for NSS Volume Deactivation event
|
||||
/**
|
||||
Callback for NSS Volume Deactivation event.
|
||||
*/
|
||||
|
||||
ulong neb_event_callback(struct EventBlock *eblock)
|
||||
|
|
@ -2075,12 +2061,11 @@ ulong neb_event_callback(struct EventBlock *eblock)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Function to get NSS volume ID of the MySQL data
|
||||
*/
|
||||
|
||||
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
|
||||
|
||||
/**
|
||||
Function to get NSS volume ID of the MySQL data.
|
||||
*/
|
||||
static void getvolumeID(BYTE *volumeName)
|
||||
{
|
||||
char path[zMAX_FULL_NAME];
|
||||
|
|
@ -2155,10 +2140,10 @@ static void start_signal_handler(void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Warn if the data is on a Traditional volume
|
||||
/**
|
||||
Warn if the data is on a Traditional volume.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
Already done by mysqld_safe
|
||||
*/
|
||||
|
||||
|
|
@ -2419,8 +2404,7 @@ static void start_signal_handler(void)
|
|||
}
|
||||
|
||||
|
||||
/* This threads handles all signals and alarms */
|
||||
|
||||
/** This threads handles all signals and alarms. */
|
||||
/* ARGSUSED */
|
||||
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||
{
|
||||
|
|
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
|
|||
#endif /* __WIN__*/
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
All global error messages are sent here where the first one is stored
|
||||
for the client
|
||||
for the client.
|
||||
*/
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
|
||||
|
||||
|
|
@ -2694,20 +2676,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
|
|||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
|
||||
|
||||
/*
|
||||
Initialize one of the global date/time format variables
|
||||
/**
|
||||
Initialize one of the global date/time format variables.
|
||||
|
||||
SYNOPSIS
|
||||
init_global_datetime_format()
|
||||
format_type What kind of format should be supported
|
||||
var_ptr Pointer to variable that should be updated
|
||||
@param format_type What kind of format should be supported
|
||||
@param var_ptr Pointer to variable that should be updated
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The default value is taken from either opt_date_time_formats[] or
|
||||
the ISO format (ANSI SQL)
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
default_service_handling()
|
||||
argv Pointer to argument list
|
||||
servicename Internal name of service
|
||||
displayname Display name of service (in taskbar ?)
|
||||
file_path Path to this program
|
||||
startup_option Startup option to mysqld
|
||||
@param argv Pointer to argument list
|
||||
@param servicename Internal name of service
|
||||
@param displayname Display name of service (in taskbar ?)
|
||||
@param file_path Path to this program
|
||||
@param startup_option Startup option to mysqld
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 option handled
|
||||
@retval
|
||||
1 Could not handle option
|
||||
*/
|
||||
*/
|
||||
|
||||
static bool
|
||||
default_service_handling(char **argv,
|
||||
|
|
@ -4213,7 +4193,7 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Execute all commands from a file. Used by the mysql_install_db script to
|
||||
create MySQL privilege tables without having to start a full MySQL server.
|
||||
*/
|
||||
|
|
@ -4342,23 +4322,17 @@ void create_thread_to_handle_connection(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Create new thread to handle incoming connection.
|
||||
|
||||
SYNOPSIS
|
||||
create_new_thread()
|
||||
thd in/out Thread handle of future thread.
|
||||
|
||||
DESCRIPTION
|
||||
This function will create new thread to handle the incoming
|
||||
connection. If there are idle cached threads one will be used.
|
||||
'thd' will be pushed into 'threads'.
|
||||
|
||||
In single-threaded mode (#define ONE_THREAD) connection will be
|
||||
In single-threaded mode (\#define ONE_THREAD) connection will be
|
||||
handled inside this function.
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
@param[in,out] thd Thread handle of future thread.
|
||||
*/
|
||||
|
||||
static void create_new_thread(THD *thd)
|
||||
|
|
@ -4712,15 +4686,13 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
|||
#endif /* __NT__ */
|
||||
|
||||
|
||||
/*
|
||||
Thread of shared memory's service
|
||||
|
||||
SYNOPSIS
|
||||
handle_connections_shared_memory()
|
||||
arg Arguments of thread
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SMEM
|
||||
|
||||
/**
|
||||
Thread of shared memory's service.
|
||||
|
||||
@param arg Arguments of thread
|
||||
*/
|
||||
pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||
{
|
||||
/* file-mapping object, use for create shared memory */
|
||||
|
|
@ -7052,13 +7024,13 @@ To see what values a running MySQL server is using, type\n\
|
|||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
|
||||
|
||||
/*
|
||||
Initialize all MySQL global variables to default values
|
||||
/**
|
||||
Initialize all MySQL global variables to default values.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_init_variables()
|
||||
We don't need to set numeric variables refered to in my_long_options
|
||||
as these are initialized by my_getopt.
|
||||
|
||||
NOTES
|
||||
@note
|
||||
The reason to set a lot of global variables to zero is to allow one to
|
||||
restart the embedded server with a clean environment
|
||||
It's also needed on some exotic platforms where global variables are
|
||||
|
|
@ -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,
|
||||
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)
|
||||
{
|
||||
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
|
||||
mysql_real_data_home.
|
||||
Return 1 if len(path) > FN_REFLEN
|
||||
@return
|
||||
1 if len(path) > FN_REFLEN
|
||||
*/
|
||||
|
||||
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 ','
|
||||
returns ~(ulong) 0 on error.
|
||||
/**
|
||||
@return
|
||||
a bitfield from a string of substrings separated by ','
|
||||
or
|
||||
~(ulong) 0 on error.
|
||||
*/
|
||||
|
||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
|
||||
|
|
@ -8136,16 +8115,16 @@ skip: ;
|
|||
} /* find_bit_type */
|
||||
|
||||
|
||||
/*
|
||||
Check if file system used for databases is case insensitive
|
||||
/**
|
||||
Check if file system used for databases is case insensitive.
|
||||
|
||||
SYNOPSIS
|
||||
test_if_case_sensitive()
|
||||
dir_name Directory to test
|
||||
@param dir_name Directory to test
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
-1 Don't know (Test failed)
|
||||
@retval
|
||||
0 File system is case sensitive
|
||||
@retval
|
||||
1 File system is case insensitive
|
||||
*/
|
||||
|
||||
|
|
@ -8176,10 +8155,11 @@ static int test_if_case_insensitive(const char *dir_name)
|
|||
}
|
||||
|
||||
|
||||
/* Create file to store pid number */
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
/**
|
||||
Create file to store pid number.
|
||||
*/
|
||||
static void create_pid_file()
|
||||
{
|
||||
File file;
|
||||
|
|
@ -8201,7 +8181,7 @@ static void create_pid_file()
|
|||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
/* Clear most status variables */
|
||||
/** Clear most status variables. */
|
||||
void refresh_status(THD *thd)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_status);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
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
|
||||
string to the value of a macro
|
||||
*/
|
||||
|
|
|
|||
137
sql/net_serv.cc
137
sql/net_serv.cc
|
|
@ -13,15 +13,16 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
This file is the net layer API for the MySQL client/server protocol,
|
||||
which is a tightly coupled, proprietary protocol owned by MySQL AB.
|
||||
@note
|
||||
Any re-implementations of this protocol must also be under GPL
|
||||
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.
|
||||
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);
|
||||
|
||||
|
||||
/* Init with packet info */
|
||||
/** Init with packet info. */
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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
|
||||
net_data_is_ready()
|
||||
sd socket descriptor
|
||||
@param sd socket descriptor
|
||||
|
||||
DESCRIPTION
|
||||
Check if there is any data to be read from the socket.
|
||||
|
||||
RETURN VALUES
|
||||
0 No data to read
|
||||
1 Data or EOF to read
|
||||
-1 Don't know if data is ready or not
|
||||
@retval
|
||||
0 No data to read
|
||||
@retval
|
||||
1 Data or EOF to read
|
||||
@retval
|
||||
-1 Don't know if data is ready or not
|
||||
*/
|
||||
|
||||
#if !defined(EMBEDDED_LIBRARY)
|
||||
|
|
@ -258,16 +256,10 @@ static int net_data_is_ready(my_socket sd)
|
|||
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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",
|
||||
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)
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -358,12 +352,13 @@ my_bool net_flush(NET *net)
|
|||
** 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)
|
||||
When compression is used a 3 byte compression length is added
|
||||
|
||||
NOTE
|
||||
@note
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
can easy add a header to a special command (like prepared statements)
|
||||
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
|
||||
juggling to put the command in there, without having to create a new
|
||||
packet.
|
||||
|
||||
This function will split big packets into sub-packets if needed.
|
||||
(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
|
||||
@retval
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
|
@ -468,33 +462,30 @@ net_write_command(NET *net,uchar command,
|
|||
net_write_buff(net, packet, len) || net_flush(net)));
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Caching the data in a local buffer before sending it.
|
||||
|
||||
SYNOPSIS
|
||||
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.
|
||||
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,
|
||||
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
|
||||
sending data.
|
||||
|
||||
NOTES
|
||||
The cached buffer can be sent as it is with 'net_flush()'.
|
||||
@param net Network handler
|
||||
@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
|
||||
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.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1
|
||||
*/
|
||||
|
||||
static my_bool
|
||||
|
|
@ -547,9 +538,12 @@ net_write_buff(NET *net, const uchar *packet, ulong len)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Read and write one packet using timeouts.
|
||||
If needed, the packet is compressed before sending.
|
||||
|
||||
@todo
|
||||
- TODO is it needed to set this variable if we have no socket
|
||||
*/
|
||||
|
||||
int
|
||||
|
|
@ -726,18 +720,17 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Help function to clear the commuication buffer when we get a too big packet.
|
||||
|
||||
SYNOPSIS
|
||||
my_net_skip_rest()
|
||||
net Communication handle
|
||||
remain Bytes to read
|
||||
alarmed Parameter for thr_alarm()
|
||||
alarm_buff Parameter for thr_alarm()
|
||||
@param net Communication handle
|
||||
@param remain Bytes to read
|
||||
@param alarmed Parameter for thr_alarm()
|
||||
@param alarm_buff Parameter for thr_alarm()
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 Was able to read the whole packet
|
||||
@retval
|
||||
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 */
|
||||
|
||||
|
||||
/*
|
||||
Reads one packet to net->buff + net->where_b
|
||||
Returns length of packet. Long packets are handled by my_net_read().
|
||||
/**
|
||||
Reads one packet to net->buff + net->where_b.
|
||||
Long packets are handled by my_net_read().
|
||||
This function reallocates the net->buff buffer if necessary.
|
||||
|
||||
@return
|
||||
Returns length of packet.
|
||||
*/
|
||||
|
||||
static ulong
|
||||
|
|
@ -972,15 +968,18 @@ end:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Read a packet from the client/server and return it without the internal
|
||||
package header.
|
||||
|
||||
If the packet is the first packet of a multi-packet packet
|
||||
(which is indicated by the length of the packet = 0xffffff) then
|
||||
all sub packets are read and concatenated.
|
||||
|
||||
If the packet was compressed, its uncompressed and the length of the
|
||||
uncompressed packet is returned.
|
||||
|
||||
@return
|
||||
The function returns the length of the found packet or packet_error.
|
||||
net->read_pos points to the read data.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
/* ------------------------------------------------------------------------
|
||||
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
|
||||
-------------------------------------------------------------------------- */
|
||||
/**
|
||||
@file
|
||||
|
||||
@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 <process.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)
|
||||
{
|
||||
|
|
@ -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:
|
||||
0 success
|
||||
1 Can't open the Service manager
|
||||
2 Failed to create service
|
||||
-------------------------------------------------------------------------- */
|
||||
- 0 success
|
||||
- 1 Can't open the Service manager
|
||||
- 2 Failed to create service.
|
||||
*/
|
||||
|
||||
|
||||
BOOL NTService::Install(int startType, LPCSTR szInternName,
|
||||
LPCSTR szDisplayName,
|
||||
|
|
@ -155,14 +162,16 @@ BOOL NTService::Install(int startType, LPCSTR szInternName,
|
|||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Remove() - Removes the service
|
||||
/**
|
||||
Removes the service.
|
||||
|
||||
nError values:
|
||||
0 success
|
||||
1 Can't open the Service manager
|
||||
2 Failed to locate service
|
||||
3 Failed to delete service
|
||||
-------------------------------------------------------------------------- */
|
||||
- 0 success
|
||||
- 1 Can't open the Service manager
|
||||
- 2 Failed to locate service
|
||||
- 3 Failed to delete service.
|
||||
*/
|
||||
|
||||
|
||||
BOOL NTService::Remove(LPCSTR szInternName)
|
||||
{
|
||||
|
|
@ -199,10 +208,10 @@ BOOL NTService::Remove(LPCSTR szInternName)
|
|||
return ret_value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
Stop() - this function should be called before the app. exits to stop
|
||||
the service
|
||||
-------------------------------------------------------------------------- */
|
||||
/**
|
||||
this function should be called before the app. exits to stop
|
||||
the service
|
||||
*/
|
||||
void NTService::Stop(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
ServiceMain() - This is the function that is called from the
|
||||
service manager to start the service
|
||||
-------------------------------------------------------------------------- */
|
||||
/**
|
||||
This is the function that is called from the
|
||||
service manager to start the service.
|
||||
*/
|
||||
|
||||
|
||||
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
|
||||
{
|
||||
|
|
@ -264,9 +274,9 @@ error:
|
|||
return;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
StartService() - starts the appliaction thread
|
||||
-------------------------------------------------------------------------- */
|
||||
/**
|
||||
starts the appliaction thread.
|
||||
*/
|
||||
|
||||
BOOL NTService::StartService()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
/* ------------------------------------------------------------------------
|
||||
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
|
||||
-------------------------------------------------------------------------- */
|
||||
/**
|
||||
@file
|
||||
|
||||
@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
|
||||
typedef void (*THREAD_FC)(void *);
|
||||
|
|
@ -13,7 +17,7 @@ class 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
|
||||
DWORD dwDesiredAccess;
|
||||
DWORD dwServiceType;
|
||||
|
|
|
|||
165
sql/opt_sum.cc
165
sql/opt_sum.cc
|
|
@ -14,7 +14,9 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
|
||||
by replacing the aggregate expression with a constant.
|
||||
|
||||
|
|
@ -22,6 +24,7 @@
|
|||
types of queries are optimised (assuming the table handler supports
|
||||
the required methods)
|
||||
|
||||
@verbatim
|
||||
SELECT COUNT(*) FROM t1[,t2,t3,...]
|
||||
SELECT MIN(b) FROM t1 WHERE a=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 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 '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
|
||||
involved tables and return the answer without any join. Thus, the
|
||||
following query will be replaced with a row of two constants:
|
||||
@verbatim
|
||||
SELECT MAX(b), MIN(d) FROM t1,t2
|
||||
WHERE a=const AND b<const AND d>const
|
||||
@endverbatim
|
||||
(assuming a index for column d of table t2 is defined)
|
||||
|
||||
*/
|
||||
|
||||
#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.
|
||||
|
||||
SYNOPSIS
|
||||
opt_sum_query()
|
||||
tables list of leaves of join table tree
|
||||
all_fields All fields to be returned
|
||||
conds WHERE clause
|
||||
@param tables list of leaves of join table tree
|
||||
@param all_fields All fields to be returned
|
||||
@param conds WHERE clause
|
||||
|
||||
NOTE:
|
||||
@note
|
||||
This function is only called for queries with sum functions and no
|
||||
GROUP BY part.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 no errors
|
||||
@retval
|
||||
1 if all items were resolved
|
||||
@retval
|
||||
HA_ERR_KEY_NOT_FOUND on impossible conditions
|
||||
OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
|
||||
wait timeout happens, for example
|
||||
@retval
|
||||
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)
|
||||
|
|
@ -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
|
||||
simple_pred()
|
||||
func_item Predicate item
|
||||
args out: Here we store the field followed by constants
|
||||
inv_order out: Is set to 1 if the predicate is of the form
|
||||
'const op field'
|
||||
@param func_item Predicate item
|
||||
@param[out] args Here we store the field followed by constants
|
||||
@param[out] inv_order 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
|
||||
constants
|
||||
constants
|
||||
@retval
|
||||
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
|
||||
contains field as its component (field_part), the function
|
||||
checks whether the condition cond is a conjunction and all its
|
||||
conjuncts referring to the columns of the same table as column
|
||||
field are one of the following forms:
|
||||
- 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 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.
|
||||
@retval
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
find_key_for_maxmin()
|
||||
max_fl in: 0 for MIN(field) / 1 for MAX(field)
|
||||
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
|
||||
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:
|
||||
|
||||
DESCRIPTION
|
||||
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
|
||||
-# 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
|
||||
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 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.
|
||||
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.
|
||||
|
||||
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
|
||||
how to apply the key for the search max/min value.
|
||||
(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
|
||||
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)
|
||||
1 Can use key to optimize MIN()/MAX()
|
||||
In this case ref, range_fl and prefix_len are updated
|
||||
*/
|
||||
@retval
|
||||
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,
|
||||
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
|
||||
reckey_in_range()
|
||||
max_fl in: 0 for MIN(field) / 1 for MAX(field)
|
||||
ref in: Reference to the key value and info
|
||||
field in: Field used the MIN/MAX expression
|
||||
cond in: WHERE condition
|
||||
range_fl in: Says whether there is a condition to to be checked
|
||||
prefix_len in: Length of the constant part of the key
|
||||
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
||||
@param[in] ref Reference to the key value and info
|
||||
@param[in] field Field used the MIN/MAX expression
|
||||
@param[in] cond WHERE condition
|
||||
@param[in] range_fl Says whether there is a condition to to be checked
|
||||
@param[in] prefix_len Length of the constant part of the key
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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
|
||||
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
|
||||
/**
|
||||
Check whether {MAX|MIN}(field) is in range specified by conditions.
|
||||
|
||||
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
|
||||
@retval
|
||||
1 WHERE was not true for the found row
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,12 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
// Text .frm files management routines
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Text .frm files management routines
|
||||
*/
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include <errno.h>
|
||||
|
|
@ -22,17 +27,16 @@
|
|||
#include <my_dir.h>
|
||||
|
||||
|
||||
/*
|
||||
write string with escaping
|
||||
/**
|
||||
Write string with escaping.
|
||||
|
||||
SYNOPSIS
|
||||
write_escaped_string()
|
||||
file - IO_CACHE for record
|
||||
val_s - string for writing
|
||||
@param file IO_CACHE for record
|
||||
@param val_s string for writing
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
TRUE - error
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
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
|
||||
write_parameter()
|
||||
file pointer to IO_CACHE structure for writing
|
||||
base pointer to data structure
|
||||
parameter pointer to parameter descriptor
|
||||
old_version for returning back old version number value
|
||||
@param file pointer to IO_CACHE structure for writing
|
||||
@param base pointer to data structure
|
||||
@param parameter pointer to parameter descriptor
|
||||
@param old_version for returning back old version number value
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
TRUE - error
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
||||
static my_bool
|
||||
write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
|
||||
ulonglong *old_version)
|
||||
|
|
@ -191,24 +195,24 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
write new .frm
|
||||
/**
|
||||
Write new .frm.
|
||||
|
||||
SYNOPSIS
|
||||
sql_create_definition_file()
|
||||
dir directory where put .frm
|
||||
file .frm file name
|
||||
type .frm type string (VIEW, TABLE)
|
||||
base base address for parameter reading (structure like
|
||||
TABLE)
|
||||
parameters parameters description
|
||||
max_versions number of versions to save
|
||||
@param dir directory where put .frm
|
||||
@param file_name .frm file name
|
||||
@param type .frm type string (VIEW, TABLE)
|
||||
@param base base address for parameter reading (structure like
|
||||
TABLE)
|
||||
@param parameters parameters description
|
||||
@param max_versions number of versions to save
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
TRUE - error
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
||||
my_bool
|
||||
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
|
||||
const LEX_STRING *type,
|
||||
|
|
@ -345,21 +349,19 @@ err_w_file:
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
Renames a frm file (including backups) in same schema
|
||||
/**
|
||||
Renames a frm file (including backups) in same schema.
|
||||
|
||||
SYNOPSIS
|
||||
rename_in_schema_file
|
||||
schema name of given schema
|
||||
old_name original file name
|
||||
new_name new file name
|
||||
revision revision number
|
||||
num_view_backups number of backups
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
1 - Error (only if renaming of frm failed)
|
||||
@param schema name of given schema
|
||||
@param old_name original file name
|
||||
@param new_name new file name
|
||||
@param revision revision number
|
||||
@param num_view_backups number of backups
|
||||
|
||||
@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,
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
Prepare frm to parse (read to memory)
|
||||
/**
|
||||
Prepare frm to parse (read to memory).
|
||||
|
||||
SYNOPSIS
|
||||
sql_parse_prepare()
|
||||
file_name - path & filename to .frm file
|
||||
mem_root - MEM_ROOT for buffer allocation
|
||||
bad_format_errors - send errors on bad content
|
||||
@param file_name path & filename to .frm file
|
||||
@param mem_root MEM_ROOT for buffer allocation
|
||||
@param bad_format_errors send errors on bad content
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
parser object
|
||||
|
||||
NOTE
|
||||
@note
|
||||
returned pointer + 1 will be type of .frm
|
||||
|
||||
@return
|
||||
0 - error
|
||||
@return
|
||||
parser object
|
||||
*/
|
||||
|
||||
File_parser *
|
||||
|
|
@ -506,22 +507,22 @@ frm_error:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
parse LEX_STRING
|
||||
/**
|
||||
parse LEX_STRING.
|
||||
|
||||
SYNOPSIS
|
||||
parse_string()
|
||||
ptr - pointer on string beginning
|
||||
end - pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
mem_root - MEM_ROOT for parameter allocation
|
||||
str - pointer on string, where results should be stored
|
||||
@param ptr pointer on string beginning
|
||||
@param end pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
@param mem_root MEM_ROOT for parameter allocation
|
||||
@param str pointer on string, where results should be stored
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
# - pointer on symbol after string
|
||||
@retval
|
||||
0 error
|
||||
@retval
|
||||
\# pointer on symbol after string
|
||||
*/
|
||||
|
||||
|
||||
static char *
|
||||
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
|
||||
read_escaped_string()
|
||||
ptr - pointer on string beginning
|
||||
eol - pointer on character after end of string
|
||||
str - target string
|
||||
@param ptr pointer on string beginning
|
||||
@param eol pointer on character after end of string
|
||||
@param str target string
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
TRUE - error
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
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
|
||||
parse_escaped_string()
|
||||
ptr - pointer on string beginning
|
||||
end - pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
mem_root - MEM_ROOT for parameter allocation
|
||||
str - pointer on string, where results should be stored
|
||||
@param ptr pointer on string beginning
|
||||
@param end pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
@param mem_root MEM_ROOT for parameter allocation
|
||||
@param str pointer on string, where results should be stored
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
# - pointer on symbol after string
|
||||
@retval
|
||||
0 error
|
||||
@retval
|
||||
\# pointer on symbol after string
|
||||
*/
|
||||
|
||||
|
||||
char *
|
||||
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
|
||||
parse_quoted_escaped_string()
|
||||
ptr - pointer on string beginning
|
||||
end - pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
mem_root - MEM_ROOT for parameter allocation
|
||||
str - pointer on string, where results should be stored
|
||||
@param ptr pointer on string beginning
|
||||
@param end pointer on symbol after parsed string end (still owned
|
||||
by buffer and can be accessed
|
||||
@param mem_root MEM_ROOT for parameter allocation
|
||||
@param str pointer on string, where results should be stored
|
||||
|
||||
RETURN
|
||||
0 - error
|
||||
# - pointer on symbol after string
|
||||
@retval
|
||||
0 error
|
||||
@retval
|
||||
\# pointer on symbol after string
|
||||
*/
|
||||
|
||||
static char *
|
||||
|
|
@ -673,18 +672,16 @@ parse_quoted_escaped_string(char *ptr, char *end,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Parser for FILE_OPTIONS_ULLLIST type value.
|
||||
|
||||
SYNOPSIS
|
||||
get_file_options_ulllist()
|
||||
ptr [in/out] pointer to parameter
|
||||
end [in] end of the configuration
|
||||
line [in] pointer to the line begining
|
||||
base [in] base address for parameter writing (structure
|
||||
like TABLE)
|
||||
parameter [in] description
|
||||
mem_root [in] MEM_ROOT for parameters allocation
|
||||
@param[in,out] ptr pointer to parameter
|
||||
@param[in] end end of the configuration
|
||||
@param[in] line pointer to the line begining
|
||||
@param[in] base base address for parameter writing (structure
|
||||
like TABLE)
|
||||
@param[in] parameter description
|
||||
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||
*/
|
||||
|
||||
bool get_file_options_ulllist(char *&ptr, char *end, char *line,
|
||||
|
|
@ -728,28 +725,28 @@ nlist_err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
parse parameters
|
||||
/**
|
||||
parse parameters.
|
||||
|
||||
SYNOPSIS
|
||||
File_parser::parse()
|
||||
base base address for parameter writing (structure like
|
||||
TABLE)
|
||||
mem_root MEM_ROOT for parameters allocation
|
||||
parameters parameters description
|
||||
required number of parameters in the above list. If the file
|
||||
contains more parameters than "required", they will
|
||||
be ignored. If the file contains less parameters
|
||||
then "required", non-existing parameters will
|
||||
remain their values.
|
||||
hook hook called for unknown keys
|
||||
hook_data some data specific for the hook
|
||||
@param base base address for parameter writing (structure like
|
||||
TABLE)
|
||||
@param mem_root MEM_ROOT for parameters allocation
|
||||
@param parameters parameters description
|
||||
@param required number of required parameters in above list. If the file
|
||||
contains more parameters than "required", they will
|
||||
be ignored. If the file contains less parameters
|
||||
then "required", non-existing parameters will
|
||||
remain their values.
|
||||
@param hook hook called for unknown keys
|
||||
@param hook_data some data specific for the hook
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
TRUE - error
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
|
||||
my_bool
|
||||
File_parser::parse(uchar* base, MEM_ROOT *mem_root,
|
||||
struct File_option *parameters, uint required,
|
||||
|
|
@ -935,26 +932,25 @@ list_err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Dummy unknown key hook
|
||||
/**
|
||||
Dummy unknown key hook.
|
||||
|
||||
SYNOPSIS
|
||||
File_parser_dummy_hook::process_unknown_string()
|
||||
unknown_key [in/out] reference on the line with unknown
|
||||
parameter and the parsing point
|
||||
base [in] base address for parameter writing (structure like
|
||||
TABLE)
|
||||
mem_root [in] MEM_ROOT for parameters allocation
|
||||
end [in] the end of the configuration
|
||||
@param[in,out] unknown_key reference on the line with unknown
|
||||
parameter and the parsing point
|
||||
@param[in] base base address for parameter writing
|
||||
(structure like TABLE)
|
||||
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||
@param[in] end the end of the configuration
|
||||
|
||||
NOTE
|
||||
@note
|
||||
This hook used to catch no longer supported keys and process them for
|
||||
backward compatibility, but it will not slow down processing of modern
|
||||
format files.
|
||||
This hook does nothing except debug output.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -20,27 +20,27 @@
|
|||
#define PARSE_FILE_TIMESTAMPLENGTH 19
|
||||
|
||||
enum file_opt_type {
|
||||
FILE_OPTIONS_STRING, /* String (LEX_STRING) */
|
||||
FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */
|
||||
FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */
|
||||
FILE_OPTIONS_REV, /* Revision version number (ulonglong) */
|
||||
FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be
|
||||
FILE_OPTIONS_STRING, /**< String (LEX_STRING) */
|
||||
FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */
|
||||
FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */
|
||||
FILE_OPTIONS_REV, /**< Revision version number (ulonglong) */
|
||||
FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be
|
||||
allocated with length 20 (19+1) */
|
||||
FILE_OPTIONS_STRLIST, /* list of escaped strings
|
||||
FILE_OPTIONS_STRLIST, /**< list of escaped strings
|
||||
(List<LEX_STRING>) */
|
||||
FILE_OPTIONS_ULLLIST /* list of ulonglong values
|
||||
FILE_OPTIONS_ULLLIST /**< list of ulonglong values
|
||||
(List<ulonglong>) */
|
||||
};
|
||||
|
||||
struct File_option
|
||||
{
|
||||
LEX_STRING name; /* Name of the option */
|
||||
int offset; /* offset to base address of value */
|
||||
file_opt_type type; /* Option type */
|
||||
LEX_STRING name; /**< Name of the option */
|
||||
int offset; /**< offset to base address of value */
|
||||
file_opt_type type; /**< Option type */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
This hook used to catch no longer supported keys and process them for
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,10 +68,13 @@ my_decimal *Item_proc_real::val_decimal(my_decimal *decimal_value)
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Setup handling of procedure
|
||||
** Return 0 if everything is ok
|
||||
*****************************************************************************/
|
||||
/**
|
||||
Setup handling of procedure.
|
||||
|
||||
@return
|
||||
Return 0 if everything is ok
|
||||
*/
|
||||
|
||||
|
||||
Procedure *
|
||||
setup_procedure(THD *thd,ORDER *param,select_result *result,
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
#pragma interface /* gcc class implementation */
|
||||
#endif
|
||||
|
||||
#define PROC_NO_SORT 1 /* Bits in flags */
|
||||
#define PROC_GROUP 2 /* proc must have group */
|
||||
#define PROC_NO_SORT 1 /**< Bits in flags */
|
||||
#define PROC_GROUP 2 /**< proc must have group */
|
||||
|
||||
/* Procedure items used by procedures to store values for send_fields */
|
||||
|
||||
|
|
|
|||
188
sql/protocol.cc
188
sql/protocol.cc
|
|
@ -13,8 +13,10 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
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
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
that shall be used only when a new connection is being
|
||||
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
|
||||
place only, my_message_sql.
|
||||
net_printf_error and net_send_error are low-level functions
|
||||
that shall be used only when a new connection is being
|
||||
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
|
||||
place only, my_message_sql.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Return ok to the client.
|
||||
|
||||
SYNOPSIS
|
||||
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)
|
||||
The ok packet has the following structure:
|
||||
|
||||
DESCRIPTION
|
||||
The ok packet has the following structure
|
||||
- 0 : Marker (1 byte)
|
||||
- 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)
|
||||
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.
|
||||
|
||||
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
|
||||
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 */
|
||||
|
||||
/*
|
||||
Send eof (= end of result set) to the client
|
||||
/**
|
||||
Send eof (= end of result set) to the client.
|
||||
|
||||
SYNOPSIS
|
||||
send_eof()
|
||||
thd Thread handler
|
||||
no_flush Set to 1 if there will be more data to the client,
|
||||
like in send_fields().
|
||||
The eof packet has the following structure:
|
||||
|
||||
DESCRIPTION
|
||||
The eof packet has the following structure
|
||||
- 254 : Marker (1 byte)
|
||||
- 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)
|
||||
warning_count Stored in 2 bytes; New in 4.1 protocol
|
||||
status_flag Stored in 2 bytes;
|
||||
For flags like SERVER_MORE_RESULTS_EXISTS
|
||||
Note that the warning count will not be sent if 'no_flush' is set as
|
||||
we don't want to report the warning count until all data is sent to the
|
||||
client.
|
||||
|
||||
Note that the warning count will not be sent if 'no_flush' is set as
|
||||
we don't want to report the warning count until all data is sent to the
|
||||
client.
|
||||
*/
|
||||
@param thd Thread handler
|
||||
@param no_flush Set to 1 if there will be more data to the client,
|
||||
like in send_fields().
|
||||
*/
|
||||
|
||||
void
|
||||
send_eof(THD *thd)
|
||||
|
|
@ -245,7 +241,7 @@ send_eof(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Format EOF packet according to the current protocol and
|
||||
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));
|
||||
}
|
||||
|
||||
/*
|
||||
Please client to send scrambled_password in old format.
|
||||
SYNOPSYS
|
||||
send_old_password_request()
|
||||
thd thread handle
|
||||
|
||||
RETURN VALUE
|
||||
0 ok
|
||||
!0 error
|
||||
/**
|
||||
Please client to send scrambled_password in old format.
|
||||
|
||||
@param thd thread handle
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
!0 error
|
||||
*/
|
||||
|
||||
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 */
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
libmysql.
|
||||
|
||||
uint is used as agrument type because of MySQL type conventions:
|
||||
uint for 0..65536
|
||||
ulong for 0..4294967296
|
||||
ulonglong for bigger numbers.
|
||||
- uint for 0..65536
|
||||
- ulong for 0..4294967296
|
||||
- ulonglong for bigger numbers.
|
||||
*/
|
||||
|
||||
static uchar *net_store_length_fast(uchar *packet, uint length)
|
||||
|
|
@ -418,27 +415,26 @@ bool Protocol::flush()
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
||||
/**
|
||||
Send name and type of result to client.
|
||||
|
||||
SYNOPSIS
|
||||
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
|
||||
Sum fields has table name empty and field_name.
|
||||
|
||||
DESCRIPTION
|
||||
Sum fields has table name empty and field_name.
|
||||
@param THD Thread data object
|
||||
@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
|
||||
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)
|
||||
{
|
||||
List_iterator_fast<Item> it(*list);
|
||||
|
|
@ -592,18 +588,17 @@ bool Protocol::write()
|
|||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
|
||||
/*
|
||||
Send \0 end terminated string
|
||||
/**
|
||||
Send \\0 end terminated string.
|
||||
|
||||
SYNOPSIS
|
||||
store()
|
||||
from NullS or \0 terminated string
|
||||
@param from NullS or \\0 terminated string
|
||||
|
||||
NOTES
|
||||
@note
|
||||
In most cases one should use store(from, length) instead of this function
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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)
|
||||
|
|
@ -669,7 +664,7 @@ bool Protocol_text::store_null()
|
|||
#endif
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Auxilary function to convert string to the given character set
|
||||
and store in network buffer.
|
||||
*/
|
||||
|
|
@ -846,13 +841,12 @@ bool Protocol_text::store(Field *field)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
/**
|
||||
@todo
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
*/
|
||||
|
||||
|
||||
bool Protocol_text::store(MYSQL_TIME *tm)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
|
|
@ -890,10 +884,10 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
TODO:
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
/**
|
||||
@todo
|
||||
Second_part format ("%06") needs to change when
|
||||
we support 0-6 decimals for time.
|
||||
*/
|
||||
|
||||
bool Protocol_text::store_time(MYSQL_TIME *tm)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
127
sql/records.cc
127
sql/records.cc
|
|
@ -14,7 +14,12 @@
|
|||
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"
|
||||
|
||||
|
|
@ -31,25 +36,20 @@ static int rr_index_first(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
|
||||
UPDATE/DELETE. Other statements perform index scans using
|
||||
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,
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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
|
||||
rr_index_first()
|
||||
info Scan info
|
||||
|
||||
RETURN
|
||||
@param info Scan info
|
||||
|
||||
@retval
|
||||
0 Ok
|
||||
-1 End of records
|
||||
1 Error
|
||||
@retval
|
||||
-1 End of records
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
|
||||
static int rr_index_first(READ_RECORD *info)
|
||||
{
|
||||
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
|
||||
rr_index()
|
||||
info Scan info
|
||||
|
||||
DESCRIPTION
|
||||
Read the next index record (in forward direction) and translate return
|
||||
value.
|
||||
|
||||
RETURN
|
||||
Read the next index record (in forward direction) and translate return
|
||||
value.
|
||||
|
||||
@param info Scan info
|
||||
|
||||
@retval
|
||||
0 Ok
|
||||
-1 End of records
|
||||
1 Error
|
||||
@retval
|
||||
-1 End of records
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
|
||||
static int rr_index(READ_RECORD *info)
|
||||
{
|
||||
int tmp= info->file->index_next(info->record);
|
||||
|
|
@ -403,22 +400,20 @@ static int rr_from_tempfile(READ_RECORD *info)
|
|||
} /* 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
|
||||
rr_unpack_from_tempfile()
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
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.
|
||||
@param info Reference to the context including record descriptors
|
||||
|
||||
RETURN
|
||||
0 - Record successfully read.
|
||||
-1 - There is no record to be read anymore.
|
||||
@retval
|
||||
0 Record successfully read.
|
||||
@retval
|
||||
-1 There is no record to be read anymore.
|
||||
*/
|
||||
|
||||
static int rr_unpack_from_tempfile(READ_RECORD *info)
|
||||
|
|
@ -456,22 +451,20 @@ static int rr_from_pointers(READ_RECORD *info)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
Read a result set record from a buffer after sorting
|
||||
/**
|
||||
Read a result set record from a buffer after sorting.
|
||||
|
||||
SYNOPSIS
|
||||
rr_unpack_from_buffer()
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
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.
|
||||
@param info Reference to the context including record descriptors
|
||||
|
||||
RETURN
|
||||
0 - Record successfully read.
|
||||
-1 - There is no record to be read anymore.
|
||||
@retval
|
||||
0 Record successfully read.
|
||||
@retval
|
||||
-1 There is no record to be read anymore.
|
||||
*/
|
||||
|
||||
static int rr_unpack_from_buffer(READ_RECORD *info)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,16 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
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"
|
||||
#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
|
||||
0 ok
|
||||
1 Error. Error message sent to client
|
||||
@return
|
||||
0 ok
|
||||
@return
|
||||
1 Error. Error message sent to client
|
||||
*/
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
@details
|
||||
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
|
||||
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,
|
||||
|
|
@ -428,9 +440,11 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
|
|||
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)
|
||||
{
|
||||
|
|
@ -466,20 +480,19 @@ bool show_new_master(THD* thd)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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 receives information about where the other slaves are.
|
||||
|
||||
SYNOPSIS
|
||||
update_slave_list()
|
||||
mysql pre-existing connection to the master
|
||||
mi master info
|
||||
@param mysql pre-existing connection to the master
|
||||
@param mi master info
|
||||
|
||||
NOTES
|
||||
@note
|
||||
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
|
||||
the master.
|
||||
|
|
@ -487,10 +500,11 @@ bool show_new_master(THD* thd)
|
|||
REPLICATION SLAVE privilege, it will pop in this function because
|
||||
SHOW SLAVE HOSTS will fail on the master.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
1 error
|
||||
@retval
|
||||
0 success
|
||||
*/
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Load all MyISAM tables from master to this slave.
|
||||
|
||||
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)
|
||||
|
|
|
|||
196
sql/set_var.cc
196
sql/set_var.cc
|
|
@ -13,9 +13,13 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
@brief
|
||||
Handling of MySQL SQL variables
|
||||
|
||||
@details
|
||||
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
|
||||
|
|
@ -28,18 +32,19 @@
|
|||
- Don't forget to initialize new fields in global_system_variables and
|
||||
max_system_variables!
|
||||
|
||||
NOTES:
|
||||
- Be careful with var->save_result: sys_var::check() only updates
|
||||
@todo
|
||||
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
|
||||
them you must first assign a value to them (in specific ::check() for
|
||||
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
|
||||
|
|
@ -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
|
||||
used lock type
|
||||
used lock 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;
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
|
|
@ -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
|
||||
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
|
||||
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)
|
||||
{
|
||||
|
|
@ -1452,9 +1457,12 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Return an Item for a variable. Used with @@[global.]variable_name
|
||||
If type is not given, return local value if exists, else global
|
||||
/**
|
||||
Return an Item for a variable.
|
||||
|
||||
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)
|
||||
|
|
@ -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,
|
||||
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)
|
||||
{
|
||||
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
|
||||
get_tmpdir()
|
||||
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.
|
||||
|
||||
DESCRIPTION
|
||||
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.
|
||||
@param thd thread handle
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
ptr pointer to NUL-terminated string
|
||||
*/
|
||||
*/
|
||||
static uchar *get_tmpdir(THD *thd)
|
||||
{
|
||||
if (opt_mysql_tmpdir)
|
||||
|
|
@ -2789,16 +2800,16 @@ static uchar *get_tmpdir(THD *thd)
|
|||
- 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
|
||||
find_option()
|
||||
opt option structure array to search in
|
||||
name variable name
|
||||
@param opt option structure array to search in
|
||||
@param name variable name
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
0 Error
|
||||
@retval
|
||||
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,
|
||||
|
|
@ -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
|
||||
intern_find_sys_var()
|
||||
str Name of system variable to find
|
||||
length Length of variable. zero means that we should use strlen()
|
||||
on the variable
|
||||
@param str Name of system variable to find
|
||||
@param length Length of variable. zero means that we should use strlen()
|
||||
on the variable
|
||||
@param no_error Refuse to emit an error, even if one occurred.
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
pointer pointer to variable definitions
|
||||
@retval
|
||||
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
|
||||
THD Thread id
|
||||
set_var List of variables to update
|
||||
This should ensure that in all normal cases none all or variables are
|
||||
updated.
|
||||
|
||||
DESCRIPTION
|
||||
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.
|
||||
@param THD Thread id
|
||||
@param var_list List of variables to update
|
||||
|
||||
This should ensure that in all normal cases none all or variables are
|
||||
updated
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
1 ERROR, message sent (normally no variables was updated)
|
||||
@retval
|
||||
-1 ERROR, message not sent
|
||||
*/
|
||||
|
||||
|
|
@ -3103,20 +3112,19 @@ err:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Say if all variables set by a SET support the ONE_SHOT keyword (currently,
|
||||
only character set and collation do; later timezones will).
|
||||
/**
|
||||
Say if all variables set by a SET support the ONE_SHOT keyword
|
||||
(currently, only character set and collation do; later timezones
|
||||
will).
|
||||
|
||||
SYNOPSIS
|
||||
@param var_list List of variables to update
|
||||
|
||||
not_all_support_one_shot
|
||||
set_var List of variables to update
|
||||
|
||||
NOTES
|
||||
@note
|
||||
It has a "not_" because it makes faster tests (no need to "!")
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 all variables of the list support ONE_SHOT
|
||||
@retval
|
||||
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
|
||||
set_var::light_check()
|
||||
thd thread handler
|
||||
@param thd thread handler
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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)
|
||||
{
|
||||
|
|
@ -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
|
||||
set_var_user::light_check()
|
||||
thd thread handler
|
||||
@param thd thread handler
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 ok
|
||||
@retval
|
||||
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)
|
||||
{
|
||||
|
|
@ -3416,13 +3424,15 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
|
|||
Functions to handle sql_mode
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Make string representation of mode
|
||||
/**
|
||||
Make string representation of mode.
|
||||
|
||||
SYNOPSIS
|
||||
thd in thread handler
|
||||
val in sql_mode value
|
||||
rep out pointer pointer to string with sql_mode representation
|
||||
@param[in] thd thread handler
|
||||
@param[in] val sql_mode value
|
||||
@param[out] len pointer on length of string
|
||||
|
||||
@return
|
||||
pointer to string with sql_mode representation
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
351
sql/sp.cc
351
sql/sp.cc
|
|
@ -249,19 +249,18 @@ Stored_routine_creation_ctx::load_from_db(THD *thd,
|
|||
|
||||
/*************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
Open the mysql.proc table for read.
|
||||
|
||||
SYNOPSIS
|
||||
open_proc_table_for_read()
|
||||
thd Thread context
|
||||
backup Pointer to Open_tables_state instance where information about
|
||||
currently open tables will be saved, and from which will be
|
||||
restored when we will end work with mysql.proc.
|
||||
@param thd Thread context
|
||||
@param backup Pointer to Open_tables_state instance where information about
|
||||
currently open tables will be saved, and from which will be
|
||||
restored when we will end work with mysql.proc.
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
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)
|
||||
|
|
@ -281,19 +280,18 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Open the mysql.proc table for update.
|
||||
|
||||
SYNOPSIS
|
||||
open_proc_table_for_update()
|
||||
thd Thread context
|
||||
@param thd Thread context
|
||||
|
||||
NOTES
|
||||
@note
|
||||
Table opened with this call should closed using close_thread_tables().
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
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)
|
||||
|
|
@ -310,19 +308,18 @@ static TABLE *open_proc_table_for_update(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Find row in open mysql.proc table representing stored routine.
|
||||
|
||||
SYNOPSIS
|
||||
db_find_routine_aux()
|
||||
thd Thread context
|
||||
type Type of routine to find (function or procedure)
|
||||
name Name of routine
|
||||
table TABLE object for open mysql.proc table.
|
||||
@param thd Thread context
|
||||
@param type Type of routine to find (function or procedure)
|
||||
@param name Name of routine
|
||||
@param table TABLE object for open mysql.proc table.
|
||||
|
||||
RETURN VALUE
|
||||
SP_OK - Routine found
|
||||
SP_KEY_NOT_FOUND- No routine with given name
|
||||
@retval
|
||||
SP_OK Routine found
|
||||
@retval
|
||||
SP_KEY_NOT_FOUND No routine with given name
|
||||
*/
|
||||
|
||||
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
|
||||
sp_head object for it.
|
||||
|
||||
SYNOPSIS
|
||||
db_find_routine()
|
||||
thd Thread context
|
||||
type Type of routine (TYPE_ENUM_PROCEDURE/...)
|
||||
name Name of routine
|
||||
sphp Out parameter in which pointer to created sp_head
|
||||
object is returned (0 in case of error).
|
||||
@param thd Thread context
|
||||
@param type Type of routine (TYPE_ENUM_PROCEDURE/...)
|
||||
@param name Name of routine
|
||||
@param 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
|
||||
idea to create temporary LEX and make it active before calling it.
|
||||
|
||||
RETURN VALUE
|
||||
0 - Success
|
||||
non-0 - Error (may be one of special codes like SP_KEY_NOT_FOUND)
|
||||
@retval
|
||||
0 Success
|
||||
@retval
|
||||
non-0 Error (may be one of special codes like SP_KEY_NOT_FOUND)
|
||||
*/
|
||||
|
||||
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
|
||||
stored procedures cache and looking into mysql.proc if needed.
|
||||
|
||||
SYNOPSIS
|
||||
sp_find_routine()
|
||||
thd - thread context
|
||||
type - type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
|
||||
name - name of procedure
|
||||
cp - hash to look routine in
|
||||
cache_only - if true perform cache-only lookup
|
||||
(Don't look in mysql.proc).
|
||||
@param thd thread context
|
||||
@param type type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
|
||||
@param name name of procedure
|
||||
@param cp hash to look routine in
|
||||
@param cache_only if true perform cache-only lookup
|
||||
(Don't look in mysql.proc).
|
||||
|
||||
RETURN VALUE
|
||||
Non-0 pointer to sp_head object for the procedure, or
|
||||
0 - in case of error.
|
||||
@retval
|
||||
NonNULL pointer to sp_head object for the procedure
|
||||
@retval
|
||||
NULL in case of error.
|
||||
*/
|
||||
|
||||
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
|
||||
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
|
||||
parsing the definition. (Used for dropping)
|
||||
parsing the definition. (Used for dropping).
|
||||
|
||||
SYNOPSIS
|
||||
sp_routine_exists_in_table()
|
||||
thd - thread context
|
||||
name - name of procedure
|
||||
@param thd thread context
|
||||
@param name name of procedure
|
||||
|
||||
RETURN VALUE
|
||||
0 - Success
|
||||
non-0 - Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
|
||||
@retval
|
||||
0 Success
|
||||
@retval
|
||||
non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
|
||||
*/
|
||||
|
||||
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
|
||||
used by statement or routine.
|
||||
*/
|
||||
|
|
@ -1538,14 +1532,16 @@ 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;
|
||||
/*
|
||||
/**
|
||||
Next element in list linking all routines in set. See also comments
|
||||
for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
|
||||
*/
|
||||
Sroutine_hash_entry *next;
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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
|
||||
- current statement (the one in thd->lex) needs table prelocking
|
||||
- first routine in thd->lex->sroutines_list needs to execute its body in
|
||||
prelocked mode.
|
||||
|
||||
SYNOPSIS
|
||||
sp_get_prelocking_info()
|
||||
thd Current thread, thd->lex is the statement to be
|
||||
checked.
|
||||
need_prelocking OUT TRUE - prelocked mode should be activated
|
||||
before executing the statement
|
||||
FALSE - Don't activate prelocking
|
||||
first_no_prelocking OUT TRUE - Tables used by first routine in
|
||||
thd->lex->sroutines_list should be
|
||||
prelocked.
|
||||
FALSE - Otherwise.
|
||||
NOTES
|
||||
@param thd Current thread, thd->lex is the statement to be
|
||||
checked.
|
||||
@param[out] need_prelocking TRUE - prelocked mode should be activated
|
||||
before executing the statement;
|
||||
FALSE - Don't activate prelocking
|
||||
@param[out] first_no_prelocking TRUE - Tables used by first routine in
|
||||
thd->lex->sroutines_list should be
|
||||
prelocked. FALSE - Otherwise.
|
||||
|
||||
@note
|
||||
This function assumes that for any "CALL proc(...)" statement routines_list
|
||||
will have 'proc' as first element (it may have several, consider e.g.
|
||||
"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
|
||||
used by statement.
|
||||
|
||||
SYNOPSIS
|
||||
add_used_routine()
|
||||
lex LEX representing statement
|
||||
arena Arena in which memory for new element will be allocated
|
||||
key Key for the hash representing set
|
||||
belong_to_view Uppermost view which uses this routine
|
||||
(0 if routine is not used by view)
|
||||
In case when statement uses stored routines but does not need
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
In case when statement uses stored routines but does not need
|
||||
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
|
||||
@todo
|
||||
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
|
||||
and directly use key values from sp_head::m_sroutines sets instead
|
||||
of making their copies.
|
||||
|
||||
RETURN VALUE
|
||||
TRUE - new element was added.
|
||||
FALSE - element was not added (because it is already present in the set).
|
||||
@retval
|
||||
TRUE new element was added.
|
||||
@retval
|
||||
FALSE element was not added (because it is already present in
|
||||
the set).
|
||||
*/
|
||||
|
||||
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
|
||||
routines used by this statement.
|
||||
|
||||
SYNOPSIS
|
||||
sp_add_used_routine()
|
||||
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/...)
|
||||
To be friendly towards prepared statements one should pass
|
||||
persistent arena as second argument.
|
||||
|
||||
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
|
||||
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,
|
||||
|
|
@ -1689,13 +1682,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Remove routines which are only indirectly used by statement from
|
||||
the set of routines used by this statement.
|
||||
|
||||
SYNOPSIS
|
||||
sp_remove_not_own_routines()
|
||||
lex LEX representing statement
|
||||
@param lex LEX representing statement
|
||||
*/
|
||||
|
||||
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
|
||||
by statements or by other routines.
|
||||
|
||||
SYNOPSIS
|
||||
sp_update_sp_used_routines()
|
||||
dst - hash to which elements should be added
|
||||
src - hash from which elements merged
|
||||
@param dst hash to which elements should be added
|
||||
@param src hash from which elements merged
|
||||
|
||||
NOTE
|
||||
@note
|
||||
This procedure won't create new Sroutine_hash_entry objects,
|
||||
instead it will simply add elements from source to destination
|
||||
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
|
||||
routines used by statement.
|
||||
|
||||
SYNOPSIS
|
||||
sp_update_stmt_used_routines()
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
src Hash representing set from which routines will be added
|
||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
||||
@param thd Thread context
|
||||
@param lex LEX representing statement
|
||||
@param src Hash representing set from which routines will
|
||||
be added
|
||||
@param 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.
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
routines used by statement.
|
||||
|
||||
SYNOPSIS
|
||||
sp_update_stmt_used_routines()
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
src List representing set from which routines will be added
|
||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
||||
@param thd Thread context
|
||||
@param lex LEX representing statement
|
||||
@param src List representing set from which routines will
|
||||
be added
|
||||
@param 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.
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
routines to statement table list. Do the same for all routines used
|
||||
by these routines.
|
||||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables_aux()
|
||||
thd - thread context
|
||||
lex - LEX representing statement
|
||||
start - first routine from the list of routines to be cached
|
||||
(this list defines mentioned sub-set).
|
||||
first_no_prelock - If true, don't add tables or cache routines used by
|
||||
the body of the first routine (i.e. *start)
|
||||
will be executed in non-prelocked mode.
|
||||
NOTE
|
||||
@param thd thread context
|
||||
@param lex LEX representing statement
|
||||
@param start first routine from the list of routines to be cached
|
||||
(this list defines mentioned sub-set).
|
||||
@param first_no_prelock If true, don't add tables or cache routines used by
|
||||
the body of the first routine (i.e. *start)
|
||||
will be executed in non-prelocked mode.
|
||||
@param tabs_changed Set to TRUE some tables were added, FALSE otherwise
|
||||
|
||||
@note
|
||||
If some function is missing this won't be reported here.
|
||||
Instead this fact will be discovered during query execution.
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
non-0 - failure
|
||||
@retval
|
||||
0 success
|
||||
@retval
|
||||
non-0 failure
|
||||
*/
|
||||
|
||||
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
|
||||
by those routines to statement table list. Do the same for all routines
|
||||
used by those routines.
|
||||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables()
|
||||
thd - thread context
|
||||
lex - LEX representing statement
|
||||
first_no_prelock - If true, don't add tables or cache routines used by
|
||||
the body of the first routine (i.e. *start)
|
||||
@param thd thread context
|
||||
@param lex LEX representing statement
|
||||
@param 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
|
||||
0 - success
|
||||
non-0 - failure
|
||||
@retval
|
||||
0 success
|
||||
@retval
|
||||
non-0 failure
|
||||
*/
|
||||
|
||||
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
|
||||
for all routines used by these routines.
|
||||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables_for_view()
|
||||
thd Thread context
|
||||
lex LEX representing statement
|
||||
view Table list element representing view
|
||||
@param thd Thread context
|
||||
@param lex LEX representing statement
|
||||
@param view Table list element representing view
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
non-0 - failure
|
||||
@retval
|
||||
0 success
|
||||
@retval
|
||||
non-0 failure
|
||||
*/
|
||||
|
||||
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 tables used by them to statement table list. Do the same for
|
||||
all implicitly used routines.
|
||||
|
||||
SYNOPSIS
|
||||
sp_cache_routines_and_add_tables_for_triggers()
|
||||
thd thread context
|
||||
lex LEX respresenting statement
|
||||
table Table list element for table with trigger
|
||||
@param thd thread context
|
||||
@param lex LEX respresenting statement
|
||||
@param table Table list element for table with trigger
|
||||
|
||||
RETURN VALUE
|
||||
0 - success
|
||||
non-0 - failure
|
||||
@retval
|
||||
0 success
|
||||
@retval
|
||||
non-0 failure
|
||||
*/
|
||||
|
||||
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.
|
||||
* Returns TRUE on success, FALSE on (alloc) failure.
|
||||
*/
|
||||
/**
|
||||
Generates the CREATE... string from the table information.
|
||||
|
||||
@return
|
||||
Returns TRUE on success, FALSE on (alloc) failure.
|
||||
*/
|
||||
static bool
|
||||
create_string(THD *thd, String *buf,
|
||||
int type,
|
||||
|
|
|
|||
396
sql/sp_head.cc
396
sql/sp_head.cc
|
|
@ -80,19 +80,20 @@ sp_map_item_type(enum enum_field_types type)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Return a string representation of the Item value.
|
||||
|
||||
NOTE: If the item has a string result type, the string is escaped
|
||||
according to its character set.
|
||||
@param thd thread handle
|
||||
@param str string buffer for representation of the value
|
||||
|
||||
SYNOPSIS
|
||||
item a pointer to the Item
|
||||
str string buffer for representation of the value
|
||||
@note
|
||||
If the item has a string result type, the string is escaped
|
||||
according to its character set.
|
||||
|
||||
RETURN
|
||||
NULL on error
|
||||
a pointer to valid a valid string on success
|
||||
@retval
|
||||
NULL on error
|
||||
@retval
|
||||
non-NULL a pointer to valid a valid string on success
|
||||
*/
|
||||
|
||||
static String *
|
||||
|
|
@ -138,16 +139,12 @@ sp_get_item_value(THD *thd, Item *item, String *str)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
sp_get_flags_for_command()
|
||||
|
||||
DESCRIPTION
|
||||
Returns a combination of:
|
||||
* 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.
|
||||
/**
|
||||
Returns a combination of:
|
||||
- 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
|
||||
|
|
@ -287,17 +284,16 @@ sp_get_flags_for_command(LEX *lex)
|
|||
return flags;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Prepare an Item for evaluation (call of fix_fields).
|
||||
|
||||
SYNOPSIS
|
||||
sp_prepare_func_item()
|
||||
thd thread handler
|
||||
it_addr pointer on item refernce
|
||||
@param thd thread handler
|
||||
@param it_addr pointer on item refernce
|
||||
|
||||
RETURN
|
||||
NULL error
|
||||
prepared item
|
||||
@retval
|
||||
NULL error
|
||||
@retval
|
||||
non-NULL prepared 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.
|
||||
|
||||
SYNOPSIS
|
||||
sp_eval_expr()
|
||||
thd - current thread object
|
||||
expr_item - the root item of the expression
|
||||
result_field - the field to store the result
|
||||
@param thd current thread object
|
||||
@param result_field the field to store the result
|
||||
@param expr_item_ptr the root item of the expression
|
||||
|
||||
RETURN VALUES
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
|
|
@ -410,6 +405,10 @@ sp_name::sp_name(THD *thd, char *key, uint key_len)
|
|||
m_explicit_name= false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Init the qualified name from the db and name.
|
||||
*/
|
||||
void
|
||||
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.
|
||||
The former is a standard requirement (and 'show status' assumes a
|
||||
non-empty name), the latter is a mysql:ism as trailing spaces are
|
||||
removed by get_field().
|
||||
|
||||
RETURN
|
||||
TRUE - bad name
|
||||
FALSE - name is ok
|
||||
|
||||
@retval
|
||||
TRUE bad name
|
||||
@retval
|
||||
FALSE name is ok
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
@ -444,7 +444,7 @@ check_routine_name(LEX_STRING *ident)
|
|||
{
|
||||
if (!ident || !ident->str || !ident->str[0] ||
|
||||
ident->str[ident->length-1] == ' ')
|
||||
{
|
||||
{
|
||||
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -778,7 +778,7 @@ sp_head::destroy()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
This is only used for result fields from functions (both during
|
||||
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
|
||||
or the query cache.
|
||||
|
||||
SYNOPSIS
|
||||
subst_spvars()
|
||||
thd Current thread.
|
||||
instr Instruction (we look for Item_splocal instances in
|
||||
instr->free_list)
|
||||
query_str Original query string
|
||||
|
||||
DESCRIPTION
|
||||
/**
|
||||
Replace thd->query{_length} with a string that one can write to
|
||||
the binlog.
|
||||
|
||||
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
|
||||
suitable for the query cache this function allocates some additional space
|
||||
for the query cache flags.
|
||||
|
||||
RETURN
|
||||
FALSE on success
|
||||
thd->query{_length} either has been appropriately replaced or there
|
||||
is no need for replacements.
|
||||
TRUE out of memory error.
|
||||
variables with NAME_CONST('sp_var_name', value) calls.
|
||||
|
||||
@param thd Current thread.
|
||||
@param instr Instruction (we look for Item_splocal instances in
|
||||
instr->free_list)
|
||||
@param query_str Original query string
|
||||
|
||||
@return
|
||||
- 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
|
||||
|
|
@ -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.
|
||||
|
||||
RETURN
|
||||
FALSE on success
|
||||
TRUE on error
|
||||
@todo
|
||||
- Will write this SP statement into binlog separately
|
||||
(TODO: consider changing the condition to "not inside event union")
|
||||
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
@ -1335,22 +1332,26 @@ sp_head::execute(THD *thd)
|
|||
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/*
|
||||
/**
|
||||
set_routine_security_ctx() changes routine security context, and
|
||||
checks if there is an EXECUTE privilege in new context. If there is
|
||||
no EXECUTE privilege, it changes the context back and returns a
|
||||
error.
|
||||
|
||||
SYNOPSIS
|
||||
set_routine_security_ctx()
|
||||
thd thread handle
|
||||
sp stored routine to change the context for
|
||||
is_proc TRUE is procedure, FALSE if function
|
||||
save_ctx pointer to an old security context
|
||||
|
||||
RETURN
|
||||
TRUE if there was a error, and the context wasn't changed.
|
||||
FALSE if the context was changed.
|
||||
@param thd thread handle
|
||||
@param sp stored routine to change the context for
|
||||
@param is_proc TRUE is procedure, FALSE if function
|
||||
@param save_ctx pointer to an old security context
|
||||
|
||||
@todo
|
||||
- Cache if the definer has the right to use the object on the
|
||||
first usage and only reset the cache if someone does a GRANT
|
||||
statement that 'may' affect this.
|
||||
|
||||
@retval
|
||||
TRUE if there was a error, and the context wasn't changed.
|
||||
@retval
|
||||
FALSE if the context was changed.
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
@ -1392,22 +1393,27 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
|
|||
/**
|
||||
Execute trigger stored program.
|
||||
|
||||
Execute a trigger:
|
||||
- changes security context for triggers;
|
||||
- switch to new memroot;
|
||||
- call sp_head::execute;
|
||||
- restore old memroot;
|
||||
- restores security context.
|
||||
- changes security context for triggers
|
||||
- switch to new memroot
|
||||
- call sp_head::execute
|
||||
- restore old memroot
|
||||
- restores security context
|
||||
|
||||
@param thd Thread context.
|
||||
@param db_name Database name.
|
||||
@param table_name Table name.
|
||||
@param grant_info GRANT_INFO structure to be filled with information
|
||||
about definer's privileges on subject table.
|
||||
@param thd Thread handle
|
||||
@param db database name
|
||||
@param table table name
|
||||
@param grant_info GRANT_INFO structure to be filled with
|
||||
information about definer's privileges
|
||||
on subject table
|
||||
|
||||
@return Error status.
|
||||
@retval FALSE on success.
|
||||
@retval TRUE on error.
|
||||
@todo
|
||||
- TODO: we should create sp_rcontext once per command and reuse it
|
||||
on subsequent executions of a trigger.
|
||||
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
bool
|
||||
|
|
@ -1515,8 +1521,9 @@ err_with_cleanup:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute a function:
|
||||
/**
|
||||
Execute a function.
|
||||
|
||||
- evaluate parameters
|
||||
- changes security context for SUID routines
|
||||
- switch to new memroot
|
||||
|
|
@ -1525,17 +1532,25 @@ err_with_cleanup:
|
|||
- evaluate the return value
|
||||
- restores security context
|
||||
|
||||
SYNOPSIS
|
||||
sp_head::execute_function()
|
||||
thd Thread handle
|
||||
argp Passed arguments (these are items from containing
|
||||
statement?)
|
||||
argcount Number of passed arguments. We need to check if this is
|
||||
correct.
|
||||
return_value_fld Save result here.
|
||||
|
||||
RETURN
|
||||
@param thd Thread handle
|
||||
@param argp Passed arguments (these are items from containing
|
||||
statement?)
|
||||
@param argcount Number of passed arguments. We need to check if
|
||||
this is correct.
|
||||
@param return_value_fld Save result here.
|
||||
|
||||
@todo
|
||||
We should create sp_rcontext once per command and reuse
|
||||
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
|
||||
@retval
|
||||
TRUE on error
|
||||
*/
|
||||
|
||||
|
|
@ -1752,14 +1767,8 @@ err_with_cleanup:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
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:
|
||||
- Set all parameters
|
||||
|
|
@ -1768,8 +1777,12 @@ err_with_cleanup:
|
|||
- copy back values of INOUT and OUT parameters
|
||||
- restores security context
|
||||
|
||||
RETURN
|
||||
@param thd Thread handle
|
||||
@param args List of values passed as arguments.
|
||||
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
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.
|
||||
|
||||
|
|
@ -2017,7 +2030,7 @@ sp_head::reset_lex(THD *thd)
|
|||
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
|
||||
sp_head::restore_lex(THD *thd)
|
||||
{
|
||||
|
|
@ -2060,6 +2073,9 @@ sp_head::restore_lex(THD *thd)
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Put the instruction on the backpatch list, associated with the label.
|
||||
*/
|
||||
void
|
||||
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
|
||||
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
|
||||
attributes).
|
||||
|
||||
SYNOPSIS
|
||||
sp_head::fill_field_definition()
|
||||
thd [IN] Thread handle
|
||||
lex [IN] Yacc parsing context
|
||||
field_type [IN] Field type
|
||||
field_def [OUT] An instance of Create_field to be filled
|
||||
@param[in] thd Thread handle
|
||||
@param[in] lex Yacc parsing context
|
||||
@param[in] field_type Field type
|
||||
@param[out] field_def An instance of create_field to be filled
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE on success
|
||||
@retval
|
||||
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
|
||||
check_show_routine_access()
|
||||
thd Thread handler
|
||||
sp SP
|
||||
full_access Set to 1 if the user has SELECT right to the
|
||||
'mysql.proc' able or is the owner of the routine
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
@param thd Thread handler
|
||||
@param sp SP
|
||||
@param full_access Set to 1 if the user has SELECT right to the
|
||||
'mysql.proc' able or is the owner of the routine
|
||||
@retval
|
||||
false ok
|
||||
@retval
|
||||
true error
|
||||
*/
|
||||
|
||||
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
|
||||
sp_head::add_instr()
|
||||
instr Instruction
|
||||
@param instr Instruction
|
||||
*/
|
||||
|
||||
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:
|
||||
1) Mark used instructions
|
||||
1.1) While doing this, shortcut jumps to jump instructions
|
||||
2) Compact the code, removing unused instructions
|
||||
-# Mark used instructions
|
||||
-# While doing this, shortcut jumps to jump instructions
|
||||
-# Compact the code, removing unused instructions.
|
||||
|
||||
This is the main mark and move loop; it relies on the following methods
|
||||
in sp_instr and its subclasses:
|
||||
|
||||
opt_mark() Mark instruction as reachable
|
||||
opt_shortcut_jump() Shortcut jumps to the final destination;
|
||||
used by opt_mark().
|
||||
opt_move() Update moved instruction
|
||||
set_destination() Set the new destination (jump instructions only)
|
||||
- opt_mark() : Mark instruction as reachable
|
||||
- opt_shortcut_jump(): Shortcut jumps to the final destination;
|
||||
used by opt_mark().
|
||||
- opt_move() : Update moved instruction
|
||||
- set_destination() : Set the new destination (jump instructions only)
|
||||
*/
|
||||
|
||||
void sp_head::optimize()
|
||||
|
|
@ -2510,9 +2526,10 @@ sp_head::opt_mark()
|
|||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/*
|
||||
/**
|
||||
Return the routine instructions as a result set.
|
||||
Returns 0 if ok, !=0 on error.
|
||||
@return
|
||||
0 if ok, !=0 on error.
|
||||
*/
|
||||
int
|
||||
sp_head::show_routine_code(THD *thd)
|
||||
|
|
@ -2575,27 +2592,25 @@ sp_head::show_routine_code(THD *thd)
|
|||
#endif // ifndef DBUG_OFF
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prepare LEX and thread for execution of instruction, if requested open
|
||||
and lock LEX's tables, execute instruction's core function, perform
|
||||
cleanup afterwards.
|
||||
|
||||
SYNOPSIS
|
||||
reset_lex_and_exec_core()
|
||||
thd - thread context
|
||||
nextp - out - next instruction
|
||||
open_tables - if TRUE then check read access to tables in LEX's table
|
||||
list and open and lock them (used in instructions which
|
||||
need to calculate some expression and don't execute
|
||||
complete statement).
|
||||
sp_instr - instruction for which we prepare context, and which core
|
||||
function execute by calling its exec_core() method.
|
||||
@param thd thread context
|
||||
@param nextp out - next instruction
|
||||
@param open_tables if TRUE then check read access to tables in LEX's table
|
||||
list and open and lock them (used in instructions which
|
||||
need to calculate some expression and don't execute
|
||||
complete statement).
|
||||
@param 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 do this once for whole routine execution in sp_head::execute().
|
||||
|
||||
RETURN VALUE
|
||||
@return
|
||||
0/non-0 - Success/Failure
|
||||
*/
|
||||
|
||||
|
|
@ -3349,6 +3364,11 @@ sp_instr_cpop::print(String *str)
|
|||
sp_instr_copen class functions
|
||||
*/
|
||||
|
||||
/**
|
||||
@todo
|
||||
Assert that we either have an error or a cursor
|
||||
*/
|
||||
|
||||
int
|
||||
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
|
||||
tables used by routine.
|
||||
|
||||
SYNOPSIS
|
||||
merge_table_list()
|
||||
thd - thread context
|
||||
table - table list
|
||||
lex_for_tmp_check - LEX of the query for which we are merging
|
||||
table list.
|
||||
@param thd thread context
|
||||
@param table table list
|
||||
@param 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
|
||||
temporary table and mark it as such in target multi-set.
|
||||
|
||||
RETURN VALUE
|
||||
TRUE - Success
|
||||
FALSE - Error
|
||||
@retval
|
||||
TRUE Success
|
||||
@retval
|
||||
FALSE Error
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
persistent between PS executions.
|
||||
|
||||
RETURN VALUE
|
||||
TRUE - if some elements were added, FALSE - otherwise.
|
||||
@param[in] thd Thread context
|
||||
@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
|
||||
|
|
@ -3865,7 +3883,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Simple function for adding an explicetly named (systems) table to
|
||||
the global table list, e.g. "mysql", "proc".
|
||||
*/
|
||||
|
|
|
|||
217
sql/sp_head.h
217
sql/sp_head.h
|
|
@ -109,7 +109,7 @@ public:
|
|||
LEX_STRING m_db;
|
||||
LEX_STRING m_name;
|
||||
LEX_STRING m_qname;
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Creates temporary sp_name object from key, used mainly
|
||||
for SP-cache lookups.
|
||||
*/
|
||||
|
|
@ -149,12 +149,12 @@ check_routine_name(LEX_STRING *ident);
|
|||
|
||||
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 &);
|
||||
|
||||
MEM_ROOT main_mem_root;
|
||||
public:
|
||||
/* Possible values of m_flags */
|
||||
/** Possible values of m_flags */
|
||||
enum {
|
||||
HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
|
||||
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
|
||||
|
|
@ -170,16 +170,16 @@ public:
|
|||
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;
|
||||
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;
|
||||
ulong m_sql_mode; // For SHOW CREATE and execution
|
||||
LEX_STRING m_qname; // db.name
|
||||
ulong m_sql_mode; ///< For SHOW CREATE and execution
|
||||
LEX_STRING m_qname; ///< db.name
|
||||
/**
|
||||
Key representing routine in the set of stored routines used by statement.
|
||||
[routine_type]db.name
|
||||
|
|
@ -211,20 +211,20 @@ public:
|
|||
|
||||
longlong m_created;
|
||||
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;
|
||||
/*
|
||||
/**
|
||||
A list of diferent recursion level instances for the same procedure.
|
||||
For every recursion level we have a sp_head instance. This instances
|
||||
connected in the list. The list ordered by increasing recursion level
|
||||
(m_recursion_level).
|
||||
*/
|
||||
sp_head *m_next_cached_sp;
|
||||
/*
|
||||
/**
|
||||
Pointer to the first element of the above list
|
||||
*/
|
||||
sp_head *m_first_instance;
|
||||
/*
|
||||
/**
|
||||
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
|
||||
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);
|
||||
*/
|
||||
sp_head *m_first_free_instance;
|
||||
/*
|
||||
/**
|
||||
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);
|
||||
*/
|
||||
sp_head *m_last_cached_sp;
|
||||
/*
|
||||
/**
|
||||
Set containing names of stored routines used by this routine.
|
||||
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
|
||||
|
|
@ -267,11 +267,11 @@ public:
|
|||
|
||||
sp_head();
|
||||
|
||||
// Initialize after we have reset mem_root
|
||||
/// Initialize after we have reset mem_root
|
||||
void
|
||||
init(LEX *lex);
|
||||
|
||||
/* Copy sp name from parser. */
|
||||
/** Copy sp name from parser. */
|
||||
void
|
||||
init_sp_name(THD *thd, sp_name *spname);
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ public:
|
|||
|
||||
virtual ~sp_head();
|
||||
|
||||
// Free memory
|
||||
/// Free memory
|
||||
void
|
||||
destroy();
|
||||
|
||||
|
|
@ -325,33 +325,41 @@ public:
|
|||
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
|
||||
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
|
||||
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
|
||||
push_backpatch(sp_instr *, struct sp_label *);
|
||||
|
||||
// Update all instruction with this label in the backpatch list to
|
||||
// the current position.
|
||||
/// Update all instruction with this label in the backpatch list to
|
||||
/// the current position.
|
||||
void
|
||||
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
|
||||
new_cont_backpatch(sp_instr_opt_meta *i);
|
||||
|
||||
// Add an instruction to the current level
|
||||
/// Add an instruction to the current level
|
||||
void
|
||||
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
|
||||
do_cont_backpatch();
|
||||
|
||||
|
|
@ -414,7 +422,7 @@ public:
|
|||
TABLE_LIST ***query_tables_last_ptr,
|
||||
TABLE_LIST *belong_to_view);
|
||||
|
||||
/*
|
||||
/**
|
||||
Check if this stored routine contains statements disallowed
|
||||
in a stored function or trigger, and set an appropriate error message
|
||||
if this is the case.
|
||||
|
|
@ -463,19 +471,19 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
|
||||
THD *m_thd; // Set if we have reset mem_root
|
||||
MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root
|
||||
THD *m_thd; ///< Set if we have reset mem_root
|
||||
|
||||
sp_pcontext *m_pcont; // Parse context
|
||||
List<LEX> m_lex; // Temp. store for the other lex
|
||||
DYNAMIC_ARRAY m_instr; // The "instructions"
|
||||
sp_pcontext *m_pcont; ///< Parse context
|
||||
List<LEX> m_lex; ///< Temp. store for the other lex
|
||||
DYNAMIC_ARRAY m_instr; ///< The "instructions"
|
||||
typedef struct
|
||||
{
|
||||
struct sp_label *lab;
|
||||
sp_instr *instr;
|
||||
} 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
|
||||
destination (in the case of a continue handler catching an error in
|
||||
the test), since it would otherwise interfere with the normal backpatch
|
||||
|
|
@ -483,15 +491,16 @@ private:
|
|||
which are to be patched differently.
|
||||
Since these occur in a more restricted way (always the same "level" in
|
||||
the code), we don't need the label.
|
||||
*/
|
||||
*/
|
||||
List<sp_instr_opt_meta> m_cont_backpatch;
|
||||
uint m_cont_level; // The current cont. backpatch level
|
||||
|
||||
/*
|
||||
/**
|
||||
Multi-set representing optimized list of tables to be locked by this
|
||||
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
|
||||
in prelocked mode and in non-prelocked mode.
|
||||
*/
|
||||
|
|
@ -506,7 +515,7 @@ private:
|
|||
*/
|
||||
void opt_mark();
|
||||
|
||||
/*
|
||||
/**
|
||||
Merge the list of tables used by query into the multi-set of tables used
|
||||
by routine.
|
||||
*/
|
||||
|
|
@ -520,16 +529,16 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
||||
uint marked;
|
||||
uint m_ip; // My index
|
||||
sp_pcontext *m_ctx; // My parse context
|
||||
uint m_ip; ///< My index
|
||||
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)
|
||||
:Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx)
|
||||
{}
|
||||
|
|
@ -538,21 +547,19 @@ public:
|
|||
{ free_items(); }
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Execute this instruction
|
||||
|
||||
SYNOPSIS
|
||||
execute()
|
||||
thd Thread handle
|
||||
nextp OUT index of the next instruction to execute. (For most
|
||||
instructions this will be the instruction following this
|
||||
one). Note that this parameter is undefined in case of
|
||||
errors, use get_cont_dest() to find the continuation
|
||||
instruction for CONTINUE error handlers.
|
||||
|
||||
RETURN
|
||||
0 on success,
|
||||
other if some error occurred
|
||||
|
||||
@param thd Thread handle
|
||||
@param[out] nextp index of the next instruction to execute. (For most
|
||||
instructions this will be the instruction following this
|
||||
one). Note that this parameter is undefined in case of
|
||||
errors, use get_cont_dest() to find the continuation
|
||||
instruction for CONTINUE error handlers.
|
||||
|
||||
@retval 0 on success,
|
||||
@retval other if some error occured
|
||||
*/
|
||||
|
||||
virtual int execute(THD *thd, uint *nextp) = 0;
|
||||
|
|
@ -590,7 +597,7 @@ public:
|
|||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||
{}
|
||||
|
||||
/*
|
||||
/**
|
||||
Mark this instruction as reachable during optimization and return the
|
||||
index to the next instruction. Jump instruction will add their
|
||||
destination to the leads list.
|
||||
|
|
@ -601,7 +608,7 @@ public:
|
|||
return m_ip+1;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Short-cut jumps to jumps during optimization. This is used by the
|
||||
jump instructions' opt_mark() methods. 'start' is the starting point,
|
||||
used to prevent the mark sweep from looping for ever. Return the
|
||||
|
|
@ -612,7 +619,7 @@ public:
|
|||
return m_ip;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Inform the instruction that it has been moved during optimization.
|
||||
Most instructions will simply update its index, but jump instructions
|
||||
must also take care of their destination pointers. Forward jumps get
|
||||
|
|
@ -626,7 +633,7 @@ public:
|
|||
}; // class sp_instr : public Sql_alloc
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Auxilary class to which instructions delegate responsibility
|
||||
for handling LEX and preparations before executing statement
|
||||
or calculating complex expression.
|
||||
|
|
@ -634,13 +641,14 @@ public:
|
|||
Exist mainly to avoid having double hierarchy between instruction
|
||||
classes.
|
||||
|
||||
TODO: Add ability to not store LEX and do any preparations if
|
||||
expression used is simple.
|
||||
@todo
|
||||
Add ability to not store LEX and do any preparations if
|
||||
expression used is simple.
|
||||
*/
|
||||
|
||||
class sp_lex_keeper
|
||||
{
|
||||
/* Prevent use of these */
|
||||
/** Prevent use of these */
|
||||
sp_lex_keeper(const sp_lex_keeper &);
|
||||
void operator=(sp_lex_keeper &);
|
||||
public:
|
||||
|
|
@ -660,10 +668,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Prepare execution of instruction using LEX, if requested check whenever
|
||||
we have read access to tables used and open/lock them, call instruction's
|
||||
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,
|
||||
sp_instr* instr);
|
||||
|
|
@ -680,7 +690,7 @@ public:
|
|||
private:
|
||||
|
||||
LEX *m_lex;
|
||||
/*
|
||||
/**
|
||||
Indicates whenever this sp_lex_keeper instance responsible
|
||||
for LEX deletion.
|
||||
*/
|
||||
|
|
@ -693,13 +703,13 @@ private:
|
|||
prelocked mode itself.
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
List of additional tables this statement needs to lock when it
|
||||
enters/leaves prelocked mode on its own.
|
||||
*/
|
||||
TABLE_LIST *prelocking_tables;
|
||||
|
||||
/*
|
||||
/**
|
||||
The value m_lex->query_tables_own_last should be set to this when the
|
||||
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
|
||||
{
|
||||
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 &);
|
||||
|
||||
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(ip, ctx), m_lex_keeper(lex, TRUE)
|
||||
|
|
@ -744,7 +754,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -767,15 +777,15 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
uint m_offset; // Frame offset
|
||||
uint m_offset; ///< Frame offset
|
||||
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;
|
||||
|
||||
}; // class sp_instr_set : public sp_instr
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Set NEW/OLD row field value instruction. Used in triggers.
|
||||
*/
|
||||
class sp_instr_set_trigger_field : public sp_instr
|
||||
|
|
@ -809,18 +819,19 @@ private:
|
|||
}; // class sp_instr_trigger_field : public sp_instr
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
An abstract class for all instructions with destinations that
|
||||
needs to be updated by the optimizer.
|
||||
|
||||
Even if not all subclasses will use both the normal destination and
|
||||
the continuation destination, we put them both here for simplicity.
|
||||
*/
|
||||
*/
|
||||
class sp_instr_opt_meta : public sp_instr
|
||||
{
|
||||
public:
|
||||
|
||||
uint m_dest; // Where we will go
|
||||
uint m_cont_dest; // Where continue handlers will go
|
||||
uint m_dest; ///< Where we will go
|
||||
uint m_cont_dest; ///< Where continue handlers will go
|
||||
|
||||
sp_instr_opt_meta(uint ip, sp_pcontext *ctx)
|
||||
: sp_instr(ip, ctx),
|
||||
|
|
@ -842,14 +853,14 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
sp_instr *m_optdest; // Used during optimization
|
||||
sp_instr *m_cont_optdest; // Used during optimization
|
||||
sp_instr *m_optdest; ///< Used during optimization
|
||||
sp_instr *m_cont_optdest; ///< Used during optimization
|
||||
|
||||
}; // class sp_instr_opt_meta : public sp_instr
|
||||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -881,7 +892,7 @@ public:
|
|||
m_dest= dest;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
Update the destination; used by the optimizer.
|
||||
*/
|
||||
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
|
||||
{
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -921,7 +932,7 @@ public:
|
|||
|
||||
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)
|
||||
{
|
||||
return m_ip;
|
||||
|
|
@ -938,7 +949,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
Item *m_expr; // The condition
|
||||
Item *m_expr; ///< The condition
|
||||
sp_lex_keeper m_lex_keeper;
|
||||
|
||||
}; // class sp_instr_jump_if_not : public sp_instr_jump
|
||||
|
|
@ -946,7 +957,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -983,7 +994,7 @@ protected:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1005,7 +1016,7 @@ public:
|
|||
|
||||
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)
|
||||
{
|
||||
return m_ip;
|
||||
|
|
@ -1018,7 +1029,7 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
int m_type; // Handler type
|
||||
int m_type; ///< Handler type
|
||||
uint m_frame;
|
||||
List<struct sp_cond_type> m_cond;
|
||||
|
||||
|
|
@ -1027,7 +1038,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1052,7 +1063,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1083,10 +1094,10 @@ private:
|
|||
}; // class sp_instr_hreturn : public sp_instr_jump
|
||||
|
||||
|
||||
/* This is DECLARE CURSOR */
|
||||
/** This is DECLARE CURSOR */
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1102,7 +1113,7 @@ public:
|
|||
|
||||
virtual void print(String *str);
|
||||
|
||||
/*
|
||||
/**
|
||||
This call is used to cleanup the instruction when a sensitive
|
||||
cursor is closed. For now stored procedures always use materialized
|
||||
cursors and the call is not used.
|
||||
|
|
@ -1111,14 +1122,14 @@ public:
|
|||
private:
|
||||
|
||||
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_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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1143,7 +1154,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1163,14 +1174,14 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
uint m_cursor; // Stack index
|
||||
uint m_cursor; ///< Stack index
|
||||
|
||||
}; // class sp_instr_copen : public sp_instr_stmt
|
||||
|
||||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1195,7 +1206,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
@ -1228,7 +1239,7 @@ private:
|
|||
|
||||
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 &);
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -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] 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
|
||||
table cache.
|
||||
Remove all instances of table from thread's open list and
|
||||
table cache.
|
||||
|
||||
@param thd Thread context
|
||||
@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 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
|
||||
which will prevent its opening (or creation) (a.k.a lock
|
||||
table name).
|
||||
Create and insert into table cache placeholder for table
|
||||
which will prevent its opening (or creation) (a.k.a lock
|
||||
table name).
|
||||
|
||||
@param thd Thread context
|
||||
@param key Table cache key for name to be locked
|
||||
|
|
@ -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
|
||||
in the table cache.
|
||||
Obtain an exclusive name lock on the table if it is not cached
|
||||
in the table cache.
|
||||
|
||||
@param thd Thread context
|
||||
@param db Name of database
|
||||
|
|
@ -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
|
||||
or in some storage engine.
|
||||
Check that table exists in table definition cache, on disk
|
||||
or in some storage engine.
|
||||
|
||||
@param thd Thread context
|
||||
@param table Table list element
|
||||
|
|
@ -3142,8 +3142,8 @@ bool reopen_table(TABLE *table)
|
|||
|
||||
|
||||
/**
|
||||
@brief Close all instances of a table open by this thread and replace
|
||||
them with exclusive name-locks.
|
||||
Close all instances of a table open by this thread and replace
|
||||
them with exclusive name-locks.
|
||||
|
||||
@param thd Thread context
|
||||
@param db Database name for the table to be closed
|
||||
|
|
@ -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,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 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
|
||||
intact so that we can re-open these quickly.
|
||||
Close handlers for tables in list, but leave the TABLE structure
|
||||
intact so that we can re-open these quickly.
|
||||
|
||||
@param thd Thread context
|
||||
@param table Head of the list of TABLE objects
|
||||
|
|
|
|||
|
|
@ -1524,7 +1524,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
|
|||
|
||||
|
||||
/**
|
||||
@brief Synchronize the thread with any flushing operations.
|
||||
Synchronize the thread with any flushing operations.
|
||||
|
||||
This helper function is called whenever a thread needs to operate on the
|
||||
query cache structure (example: during invalidation). If a table flush is in
|
||||
|
|
@ -1565,7 +1565,7 @@ void Query_cache::wait_while_table_flush_is_in_progress(bool *interrupt)
|
|||
|
||||
|
||||
/**
|
||||
@brief Remove all cached queries that uses the given database
|
||||
Remove all cached queries that uses the given database.
|
||||
*/
|
||||
|
||||
void Query_cache::invalidate(char *db)
|
||||
|
|
@ -1675,8 +1675,8 @@ void Query_cache::flush()
|
|||
|
||||
|
||||
/**
|
||||
@brief Rearrange the memory blocks and join result in cache in 1 block (if
|
||||
result length > join_limit)
|
||||
Rearrange the memory blocks and join result in cache in 1 block (if
|
||||
result length > join_limit)
|
||||
|
||||
@param[in] join_limit If the minimum length of a result block to be joined.
|
||||
@param[in] iteration_limit The maximum number of packing and joining
|
||||
|
|
@ -1946,7 +1946,7 @@ void Query_cache::make_disabled()
|
|||
|
||||
/**
|
||||
@class Query_cache
|
||||
@brief Free all resources allocated by the cache.
|
||||
Free all resources allocated by the cache.
|
||||
|
||||
This function frees all resources allocated by the cache. You
|
||||
have to call init_cache() before using the cache again. This function
|
||||
|
|
@ -1970,7 +1970,7 @@ void Query_cache::free_cache()
|
|||
|
||||
|
||||
/**
|
||||
@brief Flush the cache.
|
||||
Flush the cache.
|
||||
|
||||
This function will flush cache contents. It assumes we have
|
||||
'structure_guard_mutex' locked. The function sets the m_cache_status flag and
|
||||
|
|
@ -2516,7 +2516,7 @@ Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
|
|||
}
|
||||
|
||||
/**
|
||||
@brief Invalidate a linked list of query cache blocks.
|
||||
Invalidate a linked list of query cache blocks.
|
||||
|
||||
Each block tries to aquire a block level lock before
|
||||
free_query is a called. This function will in turn affect
|
||||
|
|
@ -2684,7 +2684,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
|
|||
|
||||
|
||||
/**
|
||||
@brief Insert used table name into the cache.
|
||||
Insert used table name into the cache.
|
||||
|
||||
@return Error status
|
||||
@retval FALSE On error
|
||||
|
|
@ -3413,8 +3413,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
|
|||
|
||||
|
||||
/**
|
||||
@brief Rearrange all memory blocks so that free memory joins at the
|
||||
'bottom' of the allocated memory block containing all cache data.
|
||||
Rearrange all memory blocks so that free memory joins at the
|
||||
'bottom' of the allocated memory block containing all cache data.
|
||||
@see Query_cache::pack(ulong join_limit, uint iteration_limit)
|
||||
*/
|
||||
|
||||
|
|
@ -4028,7 +4028,7 @@ void Query_cache::tables_dump()
|
|||
|
||||
|
||||
/**
|
||||
@brief Checks integrity of the various linked lists
|
||||
Checks integrity of the various linked lists
|
||||
|
||||
@return Error status code
|
||||
@retval FALSE Query cache is operational.
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ struct Query_cache_result;
|
|||
class Query_cache;
|
||||
|
||||
/**
|
||||
@brief This class represents a node in the linked chain of queries
|
||||
belonging to one table.
|
||||
This class represents a node in the linked chain of queries
|
||||
belonging to one 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.
|
||||
|
|
|
|||
|
|
@ -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 str initializer to be copied into lex_str
|
||||
|
|
|
|||
|
|
@ -77,10 +77,10 @@ typedef struct st_user_var_events
|
|||
was actually changed or not.
|
||||
*/
|
||||
typedef struct st_copy_info {
|
||||
ha_rows records; /* Number of processed records */
|
||||
ha_rows deleted; /* Number of deleted records */
|
||||
ha_rows updated; /* Number of updated records */
|
||||
ha_rows copied; /* Number of copied records */
|
||||
ha_rows records; /**< Number of processed records */
|
||||
ha_rows deleted; /**< Number of deleted records */
|
||||
ha_rows updated; /**< Number of updated records */
|
||||
ha_rows copied; /**< Number of copied records */
|
||||
ha_rows error_count;
|
||||
ha_rows touched; /* Number of touched records */
|
||||
enum enum_duplicates handle_duplicates;
|
||||
|
|
@ -1046,14 +1046,17 @@ public:
|
|||
*/
|
||||
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
|
||||
(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
|
||||
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
|
||||
the 'err:' label of the handle_slave_sql() in sql/slave.cc.
|
||||
|
||||
@see handle_slave_sql
|
||||
*/
|
||||
|
||||
Security_context main_security_ctx;
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@
|
|||
Declarations.
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
Sensitive_cursor -- a sensitive non-materialized server side
|
||||
cursor An instance of this class cursor has its own runtime
|
||||
cursor. An instance of this class cursor has its own runtime
|
||||
state -- list of used items and memory root for runtime memory,
|
||||
open and locked tables, change list for the changes of the
|
||||
parsed tree. This state is freed when the cursor is closed.
|
||||
|
|
@ -69,7 +69,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Materialized_cursor -- an insensitive materialized server-side
|
||||
cursor. The result set of this cursor is saved in a temporary
|
||||
table at open. The cursor itself is simply an interface for the
|
||||
|
|
@ -96,7 +96,7 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Select_materialize -- a mediator between a cursor query and the
|
||||
protocol. In case we were not able to open a non-materialzed
|
||||
cursor, it creates an internal temporary HEAP table, and insert
|
||||
|
|
@ -107,7 +107,7 @@ public:
|
|||
|
||||
class Select_materialize: public select_union
|
||||
{
|
||||
select_result *result; /* the result object of the caller (PS or SP) */
|
||||
select_result *result; /**< the result object of the caller (PS or SP) */
|
||||
public:
|
||||
Select_materialize(select_result *result_arg) :result(result_arg) {}
|
||||
virtual bool send_fields(List<Item> &list, uint flags);
|
||||
|
|
@ -116,22 +116,21 @@ public:
|
|||
|
||||
/**************************************************************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
Attempt to open a materialized or non-materialized cursor.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_open_cursor()
|
||||
thd thread handle
|
||||
flags [in] create a materialized cursor or not
|
||||
result [in] result class of the caller used as a destination
|
||||
for the rows fetched from the cursor
|
||||
pcursor [out] a pointer to store a pointer to cursor in
|
||||
@param thd thread handle
|
||||
@param[in] flags create a materialized cursor or not
|
||||
@param[in] result result class of the caller used as a destination
|
||||
for the rows fetched from the cursor
|
||||
@param[out] pcursor a pointer to store a pointer to cursor in
|
||||
|
||||
RETURN VALUE
|
||||
0 the query has been successfully executed; in this
|
||||
case pcursor may or may not contain
|
||||
a pointer to an open cursor.
|
||||
non-zero an error, 'pcursor' has been left intact.
|
||||
@retval
|
||||
0 the query has been successfully executed; in this
|
||||
case pcursor may or may not contain
|
||||
a pointer to an open cursor.
|
||||
@retval
|
||||
non-zero an error, 'pcursor' has been left intact.
|
||||
*/
|
||||
|
||||
int mysql_open_cursor(THD *thd, uint flags, select_result *result,
|
||||
|
|
@ -279,6 +278,14 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Save THD state into cursor.
|
||||
|
||||
@todo
|
||||
- XXX: thd->locked_tables is not changed.
|
||||
- What problems can we have with it if cursor is open?
|
||||
- TODO: must be fixed because of the prelocked mode.
|
||||
*/
|
||||
void
|
||||
Sensitive_cursor::post_open(THD *thd)
|
||||
{
|
||||
|
|
@ -334,6 +341,10 @@ Sensitive_cursor::post_open(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
bzero cursor state in THD.
|
||||
*/
|
||||
|
||||
void
|
||||
Sensitive_cursor::reset_thd(THD *thd)
|
||||
{
|
||||
|
|
@ -393,20 +404,13 @@ Sensitive_cursor::open(JOIN *join_arg)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
Sensitive_cursor::fetch()
|
||||
num_rows fetch up to this number of rows (maybe less)
|
||||
/**
|
||||
Fetch next num_rows rows from the cursor and send them to the client.
|
||||
|
||||
DESCRIPTION
|
||||
Fetch next num_rows rows from the cursor and send them to the client
|
||||
Precondition:
|
||||
- Sensitive_cursor is open
|
||||
|
||||
Precondition:
|
||||
Sensitive_cursor is open
|
||||
|
||||
RETURN VALUES:
|
||||
none, this function will send OK to the clinet or set an error
|
||||
message in THD
|
||||
@param num_rows fetch up to this number of rows (maybe less)
|
||||
*/
|
||||
|
||||
void
|
||||
|
|
@ -478,6 +482,11 @@ Sensitive_cursor::fetch(ulong num_rows)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@todo
|
||||
Another hack: we need to set THD state as if in a fetch to be
|
||||
able to call stmt close.
|
||||
*/
|
||||
void
|
||||
Sensitive_cursor::close()
|
||||
{
|
||||
|
|
@ -579,10 +588,9 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Fetch up to the given number of rows from a materialized cursor.
|
||||
|
||||
DESCRIPTION
|
||||
Precondition: the cursor is open.
|
||||
|
||||
If the cursor points after the last row, the fetch will automatically
|
||||
|
|
@ -590,10 +598,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
|
|||
with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
|
||||
and probably should be improved to return
|
||||
SERVER_STATUS_LAST_ROW_SENT along with the last row.
|
||||
|
||||
RETURN VALUE
|
||||
none, in case of success the row is sent to the client, otherwise
|
||||
an error message is set in THD
|
||||
*/
|
||||
|
||||
void Materialized_cursor::fetch(ulong num_rows)
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@
|
|||
#pragma interface /* gcc class interface */
|
||||
#endif
|
||||
|
||||
/*
|
||||
/**
|
||||
@file
|
||||
|
||||
Declarations for implementation of server side cursors. Only
|
||||
read-only non-scrollable cursors are currently implemented.
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
Server_side_cursor -- an interface for materialized and
|
||||
sensitive (non-materialized) implementation of cursors. All
|
||||
cursors are self-contained (created in their own memory root).
|
||||
|
|
@ -36,7 +38,7 @@
|
|||
class Server_side_cursor: protected Query_arena, public Sql_alloc
|
||||
{
|
||||
protected:
|
||||
/* Row destination used for fetch */
|
||||
/** Row destination used for fetch */
|
||||
select_result *result;
|
||||
public:
|
||||
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,
|
||||
Server_side_cursor **res);
|
||||
|
||||
/* Possible values for flags */
|
||||
|
||||
/** Possible values for flags */
|
||||
enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 };
|
||||
|
||||
#endif /* _sql_cusor_h_ */
|
||||
|
|
|
|||
773
sql/sql_parse.cc
773
sql/sql_parse.cc
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2340
sql/sql_select.cc
2340
sql/sql_select.cc
File diff suppressed because it is too large
Load diff
133
sql/sql_select.h
133
sql/sql_select.h
|
|
@ -14,7 +14,12 @@
|
|||
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
|
||||
#pragma interface /* gcc class implementation */
|
||||
|
|
@ -25,12 +30,12 @@
|
|||
|
||||
typedef struct keyuse_t {
|
||||
TABLE *table;
|
||||
Item *val; /* or value if no field */
|
||||
Item *val; /**< or value if no field */
|
||||
table_map used_tables;
|
||||
uint key, keypart, optimize;
|
||||
key_part_map keypart_map;
|
||||
ha_rows ref_table_rows;
|
||||
/*
|
||||
/**
|
||||
If true, the comparison this value was created from will not be
|
||||
satisfied if val has NULL 'value'.
|
||||
*/
|
||||
|
|
@ -53,13 +58,13 @@ class store_key;
|
|||
typedef struct st_table_ref
|
||||
{
|
||||
bool key_err;
|
||||
uint key_parts; // num of ...
|
||||
uint key_length; // length of key_buff
|
||||
int key; // key no
|
||||
uchar *key_buff; // value to look for with key
|
||||
uchar *key_buff2; // key_buff+key_length
|
||||
uint key_parts; ///< num of ...
|
||||
uint key_length; ///< length of key_buff
|
||||
int key; ///< key no
|
||||
uchar *key_buff; ///< value to look for with key
|
||||
uchar *key_buff2; ///< key_buff+key_length
|
||||
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
|
||||
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)
|
||||
*/
|
||||
bool **cond_guards;
|
||||
/*
|
||||
/**
|
||||
(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())
|
||||
*/
|
||||
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 */
|
||||
uchar *null_ref_key;
|
||||
} TABLE_REF;
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
|
||||
table
|
||||
*/
|
||||
|
|
@ -136,18 +141,18 @@ Next_select_func setup_end_select_func(JOIN *join);
|
|||
typedef struct st_join_table {
|
||||
st_join_table() {} /* Remove gcc warning */
|
||||
TABLE *table;
|
||||
KEYUSE *keyuse; /* pointer to first used key */
|
||||
KEYUSE *keyuse; /**< pointer to first used key */
|
||||
SQL_SELECT *select;
|
||||
COND *select_cond;
|
||||
QUICK_SELECT_I *quick;
|
||||
Item **on_expr_ref; /* pointer to the associated on expression */
|
||||
COND_EQUAL *cond_equal; /* multiple equalities for the on expression */
|
||||
st_join_table *first_inner; /* first inner table for including outerjoin */
|
||||
bool found; /* true after all matches or null complement */
|
||||
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 *first_upper; /* first inner table for embedding outer join */
|
||||
st_join_table *first_unmatched; /* used for optimization purposes only */
|
||||
Item **on_expr_ref; /**< pointer to the associated on expression */
|
||||
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
|
||||
st_join_table *first_inner; /**< first inner table for including outerjoin */
|
||||
bool found; /**< true after all matches or null complement */
|
||||
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 *first_upper; /**< first inner table for embedding outer join */
|
||||
st_join_table *first_unmatched; /**< used for optimization purposes only */
|
||||
|
||||
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
||||
const char *info;
|
||||
|
|
@ -168,10 +173,10 @@ typedef struct st_join_table {
|
|||
Read_record_func save_read_first_record;/* to save read_first_record */
|
||||
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
|
||||
double worst_seeks;
|
||||
key_map const_keys; /* Keys with constant part */
|
||||
key_map checked_keys; /* Keys checked in find_best */
|
||||
key_map const_keys; /**< Keys with constant part */
|
||||
key_map checked_keys; /**< Keys checked in find_best */
|
||||
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. */
|
||||
ha_rows records;
|
||||
|
|
@ -189,7 +194,7 @@ typedef struct st_join_table {
|
|||
|
||||
table_map dependent,key_dependent;
|
||||
uint use_quick,index;
|
||||
uint status; // Save status for cache
|
||||
uint status; ///< Save status for cache
|
||||
uint used_fields,used_fieldlength,used_blobs;
|
||||
enum join_type type;
|
||||
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
|
||||
|
|
@ -203,7 +208,7 @@ typedef struct st_join_table {
|
|||
TABLE_REF ref;
|
||||
JOIN_CACHE cache;
|
||||
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;
|
||||
|
||||
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
|
||||
end_of_records);
|
||||
|
||||
/*
|
||||
/**
|
||||
Information about a position of table within a join order. Used in join
|
||||
optimization.
|
||||
*/
|
||||
|
|
@ -264,25 +269,25 @@ typedef struct st_rollup
|
|||
|
||||
class JOIN :public Sql_alloc
|
||||
{
|
||||
JOIN(const JOIN &rhs); /* not implemented */
|
||||
JOIN& operator=(const JOIN &rhs); /* not implemented */
|
||||
JOIN(const JOIN &rhs); /**< not implemented */
|
||||
JOIN& operator=(const JOIN &rhs); /**< not implemented */
|
||||
public:
|
||||
JOIN_TAB *join_tab,**best_ref;
|
||||
JOIN_TAB **map2table; // mapping between table indexes and JOIN_TABs
|
||||
JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution
|
||||
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
||||
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
||||
TABLE **table,**all_tables,*sort_by_table;
|
||||
uint tables,const_tables;
|
||||
uint send_group_parts;
|
||||
bool sort_and_group,first_record,full_join,group, no_field_update;
|
||||
bool do_send_rows;
|
||||
/*
|
||||
/**
|
||||
TRUE when we want to resume nested loop iterations when
|
||||
fetching data from a cursor
|
||||
*/
|
||||
bool resume_nested_loop;
|
||||
table_map const_table_map,found_const_table_map,outer_join;
|
||||
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
||||
/*
|
||||
/**
|
||||
Used to fetch no more than given amount of rows per one
|
||||
fetch operation of server side cursor.
|
||||
The value is checked in end_send and end_send_group in fashion, similar
|
||||
|
|
@ -294,7 +299,7 @@ public:
|
|||
ha_rows fetch_limit;
|
||||
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
|
||||
|
||||
/*
|
||||
/* *
|
||||
Bitmap of nested joins embedding the position at the end of the current
|
||||
partial join (valid only during join optimizer run).
|
||||
*/
|
||||
|
|
@ -304,25 +309,25 @@ public:
|
|||
List<Item> *fields;
|
||||
List<Cached_item> group_fields, group_fields_cache;
|
||||
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;
|
||||
THD *thd;
|
||||
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;
|
||||
Procedure *procedure;
|
||||
Item *having;
|
||||
Item *tmp_having; // To store having when processed temporary table
|
||||
Item *having_history; // Store having for explain
|
||||
Item *tmp_having; ///< To store having when processed temporary table
|
||||
Item *having_history; ///< Store having for explain
|
||||
ulonglong select_options;
|
||||
select_result *result;
|
||||
TMP_TABLE_PARAM tmp_table_param;
|
||||
MYSQL_LOCK *lock;
|
||||
// unit structure (with global parameters) for this select
|
||||
/// unit structure (with global parameters) for this select
|
||||
SELECT_LEX_UNIT *unit;
|
||||
// select that processed
|
||||
/// select that processed
|
||||
SELECT_LEX *select_lex;
|
||||
/*
|
||||
/**
|
||||
TRUE <=> optimizer must not mark any table as a constant table.
|
||||
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
|
||||
|
|
@ -331,11 +336,11 @@ public:
|
|||
*/
|
||||
bool no_const_tables;
|
||||
|
||||
JOIN *tmp_join; // copy of this JOIN to be used with temporary tables
|
||||
ROLLUP rollup; // Used with rollup
|
||||
JOIN *tmp_join; ///< copy of this JOIN to be used with temporary tables
|
||||
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,
|
||||
but the group_list was emptied by optimizer, this
|
||||
flag is TRUE.
|
||||
|
|
@ -350,42 +355,42 @@ public:
|
|||
It's also set if ORDER/GROUP BY is empty.
|
||||
*/
|
||||
bool simple_order, simple_group;
|
||||
/*
|
||||
/**
|
||||
Is set only in case if we have a GROUP BY clause
|
||||
and no ORDER BY after constant elimination of '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 need_tmp, hidden_group_fields;
|
||||
DYNAMIC_ARRAY keyuse;
|
||||
Item::cond_result cond_value, having_value;
|
||||
List<Item> all_fields; // to store all fields that used in query
|
||||
//Above list changed to use temporary table
|
||||
List<Item> all_fields; ///< to store all fields that used in query
|
||||
///Above list changed to use temporary table
|
||||
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> &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;
|
||||
int error;
|
||||
|
||||
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
|
||||
COND *conds; // ---"---
|
||||
Item *conds_history; // store WHERE for explain
|
||||
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select
|
||||
List<TABLE_LIST> *join_list; // list of joined tables in reverse order
|
||||
TABLE_LIST *tables_list; ///<hold 'tables' parameter of mysql_select
|
||||
List<TABLE_LIST> *join_list; ///< list of joined tables in reverse order
|
||||
COND_EQUAL *cond_equal;
|
||||
SQL_SELECT *select; //created in optimisation phase
|
||||
JOIN_TAB *return_tab; //used only for outer joins
|
||||
Item **ref_pointer_array; //used pointer reference for this select
|
||||
SQL_SELECT *select; ///<created in optimisation phase
|
||||
JOIN_TAB *return_tab; ///<used only for outer joins
|
||||
Item **ref_pointer_array; ///<used pointer reference for this select
|
||||
// Copy of above to be used with different lists
|
||||
Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
|
||||
uint ref_pointer_array_size; // size of above in bytes
|
||||
const char *zero_result_cause; // not 0 if exec must return zero result
|
||||
uint ref_pointer_array_size; ///< size of above in bytes
|
||||
const char *zero_result_cause; ///< not 0 if exec must return zero result
|
||||
|
||||
bool union_part; // this subselect is part of union
|
||||
bool optimized; // flag to avoid double optimization in EXPLAIN
|
||||
bool union_part; ///< this subselect is part of union
|
||||
bool optimized; ///< flag to avoid double optimization in EXPLAIN
|
||||
|
||||
/*
|
||||
storage for caching buffers allocated during query execution.
|
||||
|
|
@ -494,14 +499,14 @@ public:
|
|||
int rollup_send_data(uint idx);
|
||||
int rollup_write_data(uint idx, TABLE *table);
|
||||
void remove_subq_pushed_predicates(Item **where);
|
||||
/*
|
||||
/**
|
||||
Release memory and, if possible, the open tables held by this execution
|
||||
plan (and nested plans). It's used to release some tables before
|
||||
the end of execution in order to increase concurrency and reduce
|
||||
memory consumption.
|
||||
*/
|
||||
void join_free();
|
||||
/* Cleanup this JOIN, possibly for reuse */
|
||||
/** Cleanup this JOIN, possibly for reuse */
|
||||
void cleanup(bool full);
|
||||
void clear();
|
||||
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 */
|
||||
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
|
||||
{
|
||||
|
|
@ -582,7 +587,7 @@ public:
|
|||
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
|
||||
ptr, null, 1);
|
||||
}
|
||||
virtual ~store_key() {} /* Not actually needed */
|
||||
virtual ~store_key() {} /** Not actually needed */
|
||||
virtual const char *name() const=0;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -168,7 +168,7 @@ static const LEX_STRING triggers_file_type=
|
|||
|
||||
const char * const TRG_EXT= ".TRG";
|
||||
|
||||
/*
|
||||
/**
|
||||
Table of .TRG file field descriptors.
|
||||
We have here only one field now because in nearest future .TRG
|
||||
files will be merged into .FRM files (so we don't need something
|
||||
|
|
@ -216,7 +216,7 @@ File_option sql_modes_parameters=
|
|||
FILE_OPTIONS_ULLLIST
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
This must be kept up to date whenever a new option is added to the list
|
||||
above, as it specifies the number of required parameters of the trigger in
|
||||
.trg file.
|
||||
|
|
@ -292,23 +292,27 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Create or drop trigger for table.
|
||||
|
||||
SYNOPSIS
|
||||
mysql_create_or_drop_trigger()
|
||||
thd - current thread context (including trigger definition in LEX)
|
||||
tables - table list containing one table for which trigger is created.
|
||||
create - whenever we create (TRUE) or drop (FALSE) trigger
|
||||
@param thd current thread context (including trigger definition in LEX)
|
||||
@param tables table list containing one table for which trigger is created.
|
||||
@param create whenever we create (TRUE) or drop (FALSE) trigger
|
||||
|
||||
NOTE
|
||||
@note
|
||||
This function is mainly responsible for opening and locking of table and
|
||||
invalidation of all its instances in table cache after trigger creation.
|
||||
Real work on trigger creation/dropping is done inside Table_triggers_list
|
||||
methods.
|
||||
|
||||
RETURN VALUE
|
||||
@todo
|
||||
TODO: We should check if user has TRIGGER privilege for table here.
|
||||
Now we just require SUPER privilege for creating/dropping because
|
||||
we don't have proper privilege checking for triggers in place yet.
|
||||
|
||||
@retval
|
||||
FALSE Success
|
||||
@retval
|
||||
TRUE error
|
||||
*/
|
||||
bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
|
|
@ -518,29 +522,28 @@ end:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Create trigger for table.
|
||||
|
||||
SYNOPSIS
|
||||
create_trigger()
|
||||
thd - current thread context (including trigger definition in
|
||||
LEX)
|
||||
tables - table list containing one open table for which the
|
||||
trigger is created.
|
||||
stmt_query - [OUT] after successful return, this string contains
|
||||
well-formed statement for creating this trigger.
|
||||
@param thd current thread context (including trigger definition in
|
||||
LEX)
|
||||
@param tables table list containing one open table for which the
|
||||
trigger is created.
|
||||
@param[out] stmt_query after successful return, this string contains
|
||||
well-formed statement for creation this trigger.
|
||||
|
||||
NOTE
|
||||
@note
|
||||
- Assumes that trigger name is fully qualified.
|
||||
- NULL-string means the following LEX_STRING instance:
|
||||
{ str = 0; length = 0 }.
|
||||
{ str = 0; length = 0 }.
|
||||
- In other words, definer_user and definer_host should contain
|
||||
simultaneously NULL-strings (non-SUID/old trigger) or valid strings
|
||||
(SUID/new trigger).
|
||||
simultaneously NULL-strings (non-SUID/old trigger) or valid strings
|
||||
(SUID/new trigger).
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
||||
String *stmt_query)
|
||||
|
|
@ -806,19 +809,18 @@ err_with_cleanup:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Deletes the .TRG file for a table
|
||||
/**
|
||||
Deletes the .TRG file for a table.
|
||||
|
||||
SYNOPSIS
|
||||
rm_trigger_file()
|
||||
path - char buffer of size FN_REFLEN to be used
|
||||
for constructing path to .TRG file.
|
||||
db - table's database name
|
||||
table_name - table's name
|
||||
@param path char buffer of size FN_REFLEN to be used
|
||||
for constructing path to .TRG file.
|
||||
@param db table's database name
|
||||
@param table_name table's name
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
|
||||
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
|
||||
rm_trigname_file()
|
||||
path - char buffer of size FN_REFLEN to be used
|
||||
for constructing path to .TRN file.
|
||||
db - trigger's database name
|
||||
table_name - trigger's name
|
||||
@param path char buffer of size FN_REFLEN to be used
|
||||
for constructing path to .TRN file.
|
||||
@param db trigger's database name
|
||||
@param table_name trigger's name
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
save_trigger_file()
|
||||
triggers Table_triggers_list object for which file should be saved
|
||||
db Name of database for subject table
|
||||
table_name Name of subject table
|
||||
@param triggers Table_triggers_list object for which file should be saved
|
||||
@param db Name of database for subject table
|
||||
@param table_name Name of subject table
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
FALSE Success
|
||||
@retval
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
|
|
@ -881,21 +881,26 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Drop trigger for table.
|
||||
|
||||
SYNOPSIS
|
||||
drop_trigger()
|
||||
thd - current thread context
|
||||
(including trigger definition in LEX)
|
||||
tables - table list containing one open table for which trigger
|
||||
is dropped.
|
||||
stmt_query - [OUT] after successful return, this string contains
|
||||
well-formed statement for deleting this trigger.
|
||||
@param thd current thread context
|
||||
(including trigger definition in LEX)
|
||||
@param tables table list containing one open table for which trigger
|
||||
is dropped.
|
||||
@param[out] stmt_query after successful return, this string contains
|
||||
well-formed statement for creation this trigger.
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@todo
|
||||
Probably instead of removing .TRG file we should move
|
||||
to archive directory but this should be done as part of
|
||||
parse_file.cc functionality (because we will need it
|
||||
elsewhere).
|
||||
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
|
||||
String *stmt_query)
|
||||
|
|
@ -978,18 +983,17 @@ Table_triggers_list::~Table_triggers_list()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Prepare array of Field objects referencing to TABLE::record[1] instead
|
||||
of record[0] (they will represent OLD.* row values in ON UPDATE trigger
|
||||
and in ON DELETE trigger which will be called during REPLACE execution).
|
||||
|
||||
SYNOPSIS
|
||||
prepare_record1_accessors()
|
||||
table - pointer to TABLE object for which we are creating fields.
|
||||
@param table pointer to TABLE object for which we are creating fields.
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
||||
{
|
||||
|
|
@ -1018,12 +1022,10 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Adjust Table_triggers_list with new TABLE pointer.
|
||||
|
||||
SYNOPSIS
|
||||
set_table()
|
||||
new_table - new pointer to TABLE instance
|
||||
@param new_table new pointer to TABLE instance
|
||||
*/
|
||||
|
||||
void Table_triggers_list::set_table(TABLE *new_table)
|
||||
|
|
@ -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.
|
||||
|
||||
SYNOPSIS
|
||||
check_n_load()
|
||||
thd - current thread context
|
||||
db - table's database name
|
||||
table_name - table's name
|
||||
table - pointer to table object
|
||||
names_only - stop after loading trigger names
|
||||
@param thd current thread context
|
||||
@param db table's database name
|
||||
@param table_name table's name
|
||||
@param table pointer to table object
|
||||
@param names_only stop after loading trigger names
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@todo
|
||||
A lot of things to do here e.g. how about other funcs and being
|
||||
more paranoical ?
|
||||
|
||||
@todo
|
||||
This could be avoided if there is no triggers for UPDATE and DELETE.
|
||||
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
|
||||
bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
||||
|
|
@ -1433,24 +1441,23 @@ err_with_lex_cleanup:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Obtains and returns trigger metadata
|
||||
/**
|
||||
Obtains and returns trigger metadata.
|
||||
|
||||
SYNOPSIS
|
||||
get_trigger_info()
|
||||
thd - current thread context
|
||||
event - trigger event type
|
||||
time_type - trigger action time
|
||||
name - returns name of trigger
|
||||
stmt - returns statement of trigger
|
||||
sql_mode - returns sql_mode of trigger
|
||||
definer_user - returns definer/creator of trigger. The caller is
|
||||
responsible to allocate enough space for storing definer
|
||||
information.
|
||||
@param thd current thread context
|
||||
@param event trigger event type
|
||||
@param time_type trigger action time
|
||||
@param trigger_name returns name of trigger
|
||||
@param trigger_stmt returns statement of trigger
|
||||
@param sql_mode returns sql_mode of trigger
|
||||
@param definer returns definer/creator of trigger. The caller is
|
||||
responsible to allocate enough space for storing
|
||||
definer information.
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
|
||||
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.
|
||||
|
||||
SYNOPSIS
|
||||
drop_all_triggers()
|
||||
thd - current thread context
|
||||
db - schema for table
|
||||
name - name for table
|
||||
@param thd current thread context
|
||||
@param db schema for table
|
||||
@param name name for table
|
||||
|
||||
NOTE
|
||||
@note
|
||||
The calling thread should hold the LOCK_open mutex;
|
||||
|
||||
RETURN VALUE
|
||||
False - success
|
||||
True - error
|
||||
@retval
|
||||
False success
|
||||
@retval
|
||||
True error
|
||||
*/
|
||||
|
||||
bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
|
||||
|
|
@ -1680,19 +1686,18 @@ end:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Update .TRG file after renaming triggers' subject table
|
||||
(change name of table in triggers' definitions).
|
||||
|
||||
SYNOPSIS
|
||||
change_table_name_in_triggers()
|
||||
thd Thread context
|
||||
db_name Database of subject table
|
||||
old_table_name Old subject table's name
|
||||
new_table_name New subject table's name
|
||||
@param thd Thread context
|
||||
@param db_name Database of subject table
|
||||
@param old_table_name Old subject table's name
|
||||
@param new_table_name New subject table's name
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
FALSE Success
|
||||
@retval
|
||||
TRUE Failure
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
after renaming triggers' subject table.
|
||||
/**
|
||||
Iterate though Table_triggers_list::names_list list and update
|
||||
.TRN files after renaming triggers' subject table.
|
||||
|
||||
SYNOPSIS
|
||||
change_table_name_in_trignames()
|
||||
db_name Database of subject table
|
||||
new_table_name New subject table's name
|
||||
stopper Pointer to Table_triggers_list::names_list at
|
||||
which we should stop updating.
|
||||
@param db_name Database of subject table
|
||||
@param new_table_name New subject table's name
|
||||
@param stopper Pointer to Table_triggers_list::names_list at
|
||||
which we should stop updating.
|
||||
|
||||
RETURN VALUE
|
||||
@retval
|
||||
0 Success
|
||||
@retval
|
||||
non-0 Failure, pointer to Table_triggers_list::names_list element
|
||||
for which update failed.
|
||||
for which update failed.
|
||||
*/
|
||||
|
||||
LEX_STRING*
|
||||
|
|
@ -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] 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
|
||||
mark_fields_used()
|
||||
thd Current thread context
|
||||
event Type of event triggers for which we are going to ins
|
||||
This method marks fields of subject table which are read/set in its
|
||||
triggers as such (by properly updating TABLE::read_set/write_set)
|
||||
and thus informs handler that values for these fields should be
|
||||
retrieved/stored during execution of statement.
|
||||
|
||||
DESCRIPTION
|
||||
This method marks fields of subject table which are read/set in its
|
||||
triggers as such (by properly updating TABLE::read_set/write_set)
|
||||
and thus informs handler that values for these fields should be
|
||||
retrieved/stored during execution of statement.
|
||||
@param thd Current thread context
|
||||
@param event Type of event triggers for which we are going to inspect
|
||||
*/
|
||||
|
||||
void Table_triggers_list::mark_fields_used(trg_event_type event)
|
||||
|
|
@ -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
|
||||
Handle_old_incorrect_sql_modes_hook::process_unknown_string()
|
||||
unknown_key [in/out] reference on the line with unknown
|
||||
parameter and the parsing point
|
||||
base [in] base address for parameter writing (structure
|
||||
like TABLE)
|
||||
mem_root [in] MEM_ROOT for parameters allocation
|
||||
end [in] the end of the configuration
|
||||
@param[in,out] unknown_key reference on the line with unknown
|
||||
parameter and the parsing point
|
||||
@param[in] base base address for parameter writing
|
||||
(structure like TABLE)
|
||||
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||
@param[in] end the end of the configuration
|
||||
|
||||
NOTE: this hook process back compatibility for incorrectly written
|
||||
sql_modes parameter (see BUG#14090).
|
||||
@note
|
||||
NOTE: this hook process back compatibility for incorrectly written
|
||||
sql_modes parameter (see BUG#14090).
|
||||
|
||||
RETURN
|
||||
@retval
|
||||
FALSE OK
|
||||
@retval
|
||||
TRUE Error
|
||||
*/
|
||||
|
||||
|
|
@ -2068,13 +2070,12 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
#define INVALID_TRIGGER_TABLE_LENGTH 15
|
||||
|
||||
/**
|
||||
Trigger BUG#15921 compatibility hook. For details see
|
||||
Handle_old_incorrect_sql_modes_hook::process_unknown_string().
|
||||
*/
|
||||
|
||||
#define INVALID_TRIGGER_TABLE_LENGTH 15
|
||||
|
||||
bool
|
||||
Handle_old_incorrect_trigger_table_hook::
|
||||
process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
|
||||
|
|
@ -2113,9 +2114,9 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
|
|||
/**
|
||||
Contruct path to TRN-file.
|
||||
|
||||
@param[in] thd Thread context.
|
||||
@param[in] trg_name Trigger name.
|
||||
@param[out] trn_path Variable to store constructed path
|
||||
@param thd[in] Thread context.
|
||||
@param trg_name[in] Trigger name.
|
||||
@param trn_path[out] Variable to store constructed path
|
||||
*/
|
||||
|
||||
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
|
||||
|
|
@ -2148,10 +2149,10 @@ bool check_trn_exists(const LEX_STRING *trn_path)
|
|||
/**
|
||||
Retrieve table name for given trigger.
|
||||
|
||||
@param[in] thd Thread context.
|
||||
@param[in] trg_name Trigger name.
|
||||
@param[in] trn_path Path to the corresponding TRN-file.
|
||||
@param[out] tbl_name Variable to store retrieved table name.
|
||||
@param thd[in] Thread context.
|
||||
@param trg_name[in] Trigger name.
|
||||
@param trn_path[in] Path to the corresponding TRN-file.
|
||||
@param tbl_name[out] Variable to store retrieved table name.
|
||||
|
||||
@return Error status.
|
||||
@retval FALSE on success.
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
This class holds all information about triggers of table.
|
||||
|
||||
QQ: Will it be merged into TABLE in the future ?
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
|
||||
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];
|
||||
/*
|
||||
/**
|
||||
Heads of the lists linking items for all fields used in triggers
|
||||
grouped by event and action_time.
|
||||
*/
|
||||
Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||
/*
|
||||
/**
|
||||
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
|
||||
trigger and DELETE trigger when it is called for REPLACE).
|
||||
*/
|
||||
Field **record1_field;
|
||||
/*
|
||||
/**
|
||||
During execution of trigger new_field and old_field should point to the
|
||||
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)
|
||||
|
|
@ -45,30 +45,30 @@ class Table_triggers_list: public Sql_alloc
|
|||
|
||||
/* TABLE instance for which this triggers list object was created */
|
||||
TABLE *trigger_table;
|
||||
/*
|
||||
/**
|
||||
Names of triggers.
|
||||
Should correspond to order of triggers on definitions_list,
|
||||
used in CREATE/DROP TRIGGER for looking up trigger by name.
|
||||
*/
|
||||
List<LEX_STRING> names_list;
|
||||
/*
|
||||
/**
|
||||
List of "ON table_name" parts in trigger definitions, used for
|
||||
updating trigger definitions during RENAME TABLE.
|
||||
*/
|
||||
List<LEX_STRING> on_table_names_list;
|
||||
|
||||
/*
|
||||
/**
|
||||
Grant information for each trigger (pair: subject table, trigger definer).
|
||||
*/
|
||||
GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||
|
||||
public:
|
||||
/*
|
||||
/**
|
||||
Field responsible for storing triggers definitions in file.
|
||||
It have to be public because we are using it directly from parser.
|
||||
*/
|
||||
List<LEX_STRING> definitions_list;
|
||||
/*
|
||||
/**
|
||||
List of sql modes for triggers
|
||||
*/
|
||||
List<ulonglong> definition_modes_list;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ static bool check_fields(THD *thd, List<Item> &items)
|
|||
|
||||
|
||||
/**
|
||||
@brief Re-read record if more columns are needed for error message.
|
||||
Re-read record if more columns are needed for error message.
|
||||
|
||||
If we got a duplicate key error, we want to write an error
|
||||
message containing the value of the duplicate key. If we do not have
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
|
|||
|
||||
|
||||
/**
|
||||
@brief Creating/altering VIEW procedure
|
||||
Creating/altering VIEW procedure
|
||||
|
||||
@param thd thread handler
|
||||
@param views views to create
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ typedef struct user_conn {
|
|||
char *user;
|
||||
/* Pointer to host part of the key. */
|
||||
char *host;
|
||||
/*
|
||||
/**
|
||||
The moment of time when per hour counters were reset last time
|
||||
(i.e. start of "hour" for conn_per_hour, updates, questions counters).
|
||||
*/
|
||||
|
|
|
|||
12
sql/tztime.h
12
sql/tztime.h
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#if !defined(TESTTIME) && !defined(TZINFO2SQL)
|
||||
|
||||
/*
|
||||
/**
|
||||
This class represents abstract time zone and provides
|
||||
basic interface for MYSQL_TIME <-> my_time_t conversion.
|
||||
Actual time zones which are specified by DB, or via offset
|
||||
|
|
@ -30,7 +30,7 @@ class Time_zone: public Sql_alloc
|
|||
{
|
||||
public:
|
||||
Time_zone() {} /* Remove gcc warning */
|
||||
/*
|
||||
/**
|
||||
Converts local time in broken down MYSQL_TIME representation to
|
||||
my_time_t (UTC seconds since Epoch) represenation.
|
||||
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,
|
||||
my_bool *in_dst_time_gap) const = 0;
|
||||
/*
|
||||
/**
|
||||
Converts time in my_time_t representation to local time in
|
||||
broken down MYSQL_TIME representation.
|
||||
*/
|
||||
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
|
||||
have to be already zeroended to be able to use String::ptr() instead
|
||||
of c_ptr().
|
||||
*/
|
||||
virtual const String * get_name() const = 0;
|
||||
|
||||
/*
|
||||
/**
|
||||
We need this only for surpressing warnings, objects of this type are
|
||||
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 my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
|
||||
|
||||
/*
|
||||
/**
|
||||
Number of elements in table list produced by my_tz_get_table_list()
|
||||
(this table list contains tables which are needed for dynamical loading
|
||||
of time zone descriptions). Actually it is imlementation detail that
|
||||
|
|
|
|||
10
sql/unireg.h
10
sql/unireg.h
|
|
@ -155,34 +155,34 @@
|
|||
#define OPEN_VIEW 8192 /* Allow open on view */
|
||||
#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view,
|
||||
but do not parse view itself */
|
||||
/*
|
||||
/**
|
||||
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
|
||||
The flag means that we need to open FRM file only to get necessary data.
|
||||
*/
|
||||
#define OPEN_FRM_FILE_ONLY 32768
|
||||
/*
|
||||
/**
|
||||
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
|
||||
The flag means that we need to process tables only to get necessary data.
|
||||
Views are not processed.
|
||||
*/
|
||||
#define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2
|
||||
/*
|
||||
/**
|
||||
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
|
||||
The flag means that we need to process views only to get necessary data.
|
||||
Tables are not processed.
|
||||
*/
|
||||
#define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
The flag means that we need to open a view using
|
||||
open_normal_and_derived_tables() function.
|
||||
*/
|
||||
#define OPEN_VIEW_FULL OPEN_VIEW_ONLY*2
|
||||
/*
|
||||
/**
|
||||
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.
|
||||
The flag means that I_S table uses optimization algorithm.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue