mirror of
https://github.com/MariaDB/server.git
synced 2026-05-03 13:45:34 +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 sql/field.cc: Auto merged sql/filesort.cc: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/handler.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_create.cc: Auto merged sql/item_func.cc: Auto merged sql/item_geofunc.cc: Auto merged sql/item_strfunc.cc: Auto merged sql/item_subselect.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_timefunc.cc: Auto merged sql/log.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/net_serv.cc: Auto merged sql/opt_sum.cc: Auto merged sql/protocol.h: Auto merged sql/records.cc: Auto merged sql/set_var.cc: Auto merged sql/sp.cc: Auto merged sql/sp_head.h: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_trigger.cc: Auto merged sql/sql_update.cc: Auto merged sql/sql_view.cc: Auto merged sql/structs.h: Auto merged sql/unireg.h: Auto merged sql/item.cc: manual merge sql/log_event.cc: manual merge sql/protocol.cc: manual merge sql/sp_head.cc: manual merge sql/sql_base.cc: manual merge sql/sql_parse.cc: manual merge sql/sql_select.cc: manual merge
This commit is contained in:
commit
18f5e87ed9
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Read language depeneded messagefile */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Read language depeneded messagefile
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "mysys_err.h"
|
#include "mysys_err.h"
|
||||||
|
|
@ -23,20 +28,17 @@ static bool read_texts(const char *file_name,const char ***point,
|
||||||
uint error_messages);
|
uint error_messages);
|
||||||
static void init_myfunc_errs(void);
|
static void init_myfunc_errs(void);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read messages from errorfile.
|
Read messages from errorfile.
|
||||||
|
|
||||||
SYNOPSIS
|
This function can be called multiple times to reload the messages.
|
||||||
init_errmessage()
|
If it fails to load the messages, it will fail softly by initializing
|
||||||
|
the errmesg pointer to an array of empty strings or by keeping the
|
||||||
|
old array if it exists.
|
||||||
|
|
||||||
DESCRIPTION
|
@retval
|
||||||
This function can be called multiple times to reload the messages.
|
|
||||||
If it fails to load the messages, it will fail softly by initializing
|
|
||||||
the errmesg pointer to an array of empty strings or by keeping the
|
|
||||||
old array if it exists.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -75,7 +77,14 @@ bool init_errmessage(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read text from packed textfile in language-directory */
|
/**
|
||||||
|
Read text from packed textfile in language-directory.
|
||||||
|
|
||||||
|
If we can't read messagefile then it's panic- we can't continue.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Convert the character set to server system character set
|
||||||
|
*/
|
||||||
|
|
||||||
static bool read_texts(const char *file_name,const char ***point,
|
static bool read_texts(const char *file_name,const char ***point,
|
||||||
uint error_messages)
|
uint error_messages)
|
||||||
|
|
@ -178,7 +187,9 @@ err1:
|
||||||
} /* read_texts */
|
} /* read_texts */
|
||||||
|
|
||||||
|
|
||||||
/* Initiates error-messages used by my_func-library */
|
/**
|
||||||
|
Initiates error-messages used by my_func-library.
|
||||||
|
*/
|
||||||
|
|
||||||
static void init_myfunc_errs()
|
static void init_myfunc_errs()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,18 @@
|
||||||
struct st_des_keyschedule des_keyschedule[10];
|
struct st_des_keyschedule des_keyschedule[10];
|
||||||
uint des_default_key;
|
uint des_default_key;
|
||||||
|
|
||||||
/*
|
#define des_cs &my_charset_latin1
|
||||||
Function which loads DES keys from plaintext file into memory on MySQL
|
|
||||||
server startup and on command FLUSH DES_KEY_FILE.
|
|
||||||
Blame tonu@spam.ee on bugs ;)
|
|
||||||
|
|
||||||
RETURN
|
/**
|
||||||
0 ok
|
Load DES keys from plaintext file into
|
||||||
1 Error
|
memory on MySQL server startup and on command FLUSH DES_KEY_FILE.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 ok
|
||||||
|
@retval
|
||||||
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define des_cs &my_charset_latin1
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
load_des_key_file(const char *file_name)
|
load_des_key_file(const char *file_name)
|
||||||
|
|
|
||||||
|
|
@ -14,29 +14,33 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Functions for discover of frm file from handler */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Functions for discover of frm file from handler
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read the contents of a .frm file
|
Read the contents of a .frm file.
|
||||||
|
|
||||||
SYNOPSIS
|
frmdata and len are set to 0 on error.
|
||||||
readfrm()
|
|
||||||
|
|
||||||
name path to table-file "db/name"
|
@param name path to table-file "db/name"
|
||||||
frmdata frm data
|
@param frmdata frm data
|
||||||
len length of the read frmdata
|
@param len length of the read frmdata
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
1 Could not open file
|
@retval
|
||||||
2 Could not stat file
|
1 Could not open file
|
||||||
3 Could not allocate data for read
|
@retval
|
||||||
Could not read file
|
2 Could not stat file
|
||||||
|
@retval
|
||||||
frmdata and len are set to 0 on error
|
3 Could not allocate data for read. Could not read file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int readfrm(const char *name, uchar **frmdata, size_t *len)
|
int readfrm(const char *name, uchar **frmdata, size_t *len)
|
||||||
|
|
@ -87,18 +91,16 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Write the content of a frm data pointer
|
Write the content of a frm data pointer
|
||||||
to a frm file
|
to a frm file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param name path to table-file "db/name"
|
||||||
writefrm()
|
@param frmdata frm data
|
||||||
|
@param len length of the frmdata
|
||||||
|
|
||||||
name path to table-file "db/name"
|
@retval
|
||||||
frmdata frm data
|
0 ok
|
||||||
len length of the frmdata
|
@retval
|
||||||
|
2 Could not write file
|
||||||
RETURN VALUES
|
|
||||||
0 ok
|
|
||||||
2 Could not write file
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int writefrm(const char *name, const uchar *frmdata, size_t len)
|
int writefrm(const char *name, const uchar *frmdata, size_t len)
|
||||||
|
|
|
||||||
513
sql/field.cc
513
sql/field.cc
|
|
@ -14,9 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/**
|
||||||
** This file implements classes defined in field.h
|
@file
|
||||||
*****************************************************************************/
|
|
||||||
|
@brief
|
||||||
|
This file implements classes defined in field.h
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -913,14 +916,13 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return type of which can carry value of both given types in UNION result
|
Return type of which can carry value of both given types in UNION result.
|
||||||
|
|
||||||
SYNOPSIS
|
@param a type for merging
|
||||||
Field::field_type_merge()
|
@param b type for merging
|
||||||
a, b types for merging
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
type of field
|
type of field
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -992,14 +994,12 @@ test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Detect Item_result by given field type of UNION merge result
|
Detect Item_result by given field type of UNION merge result.
|
||||||
|
|
||||||
SYNOPSIS
|
@param field_type given field type
|
||||||
Field::result_merge_type()
|
|
||||||
field_type given field type
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Item_result (type of internal MySQL expression result)
|
Item_result (type of internal MySQL expression result)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1015,18 +1015,17 @@ Item_result Field::result_merge_type(enum_field_types field_type)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether a field type can be partially indexed by a key
|
Check whether a field type can be partially indexed by a key.
|
||||||
|
|
||||||
This is a static method, rather than a virtual function, because we need
|
This is a static method, rather than a virtual function, because we need
|
||||||
to check the type of a non-Field in mysql_alter_table().
|
to check the type of a non-Field in mysql_alter_table().
|
||||||
|
|
||||||
SYNOPSIS
|
@param type field type
|
||||||
type_can_have_key_part()
|
|
||||||
type field type
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
TRUE Type can have a prefixed key
|
TRUE Type can have a prefixed key
|
||||||
|
@retval
|
||||||
FALSE Type can not have a prefixed key
|
FALSE Type can not have a prefixed key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1048,8 +1047,8 @@ bool Field::type_can_have_key_part(enum enum_field_types type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Numeric fields base class constructor
|
Numeric fields base class constructor.
|
||||||
*/
|
*/
|
||||||
Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
Field_num::Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg, utype unireg_check_arg,
|
uchar null_bit_arg, utype unireg_check_arg,
|
||||||
|
|
@ -1080,23 +1079,25 @@ void Field_num::prepend_zeros(String *value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Test if given number is a int.
|
Test if given number is a int.
|
||||||
|
|
||||||
SYNOPSIS
|
@todo
|
||||||
Field_num::check_int
|
Make this multi-byte-character safe
|
||||||
cs Character set
|
|
||||||
str String to test
|
|
||||||
end Pointer to char after last used digit
|
|
||||||
length String length
|
|
||||||
error Error returned by strntoull10rnd()
|
|
||||||
|
|
||||||
NOTE
|
@param str String to test
|
||||||
|
@param length Length of 'str'
|
||||||
|
@param int_end Pointer to char after last used digit
|
||||||
|
@param cs Character set
|
||||||
|
|
||||||
|
@note
|
||||||
This is called after one has called strntoull10rnd() function.
|
This is called after one has called strntoull10rnd() function.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 OK
|
||||||
|
@retval
|
||||||
1 error: empty string or wrong integer.
|
1 error: empty string or wrong integer.
|
||||||
|
@retval
|
||||||
2 error: garbage at the end of string.
|
2 error: garbage at the end of string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1191,16 +1192,15 @@ out_of_range:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Process decimal library return codes and issue warnings for overflow and
|
Process decimal library return codes and issue warnings for overflow and
|
||||||
truncation.
|
truncation.
|
||||||
|
|
||||||
SYNOPSIS
|
@param op_result decimal library return code (E_DEC_* see include/decimal.h)
|
||||||
Field::warn_if_overflow()
|
|
||||||
op_result decimal library return code (E_DEC_* see include/decimal.h)
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
1 there was overflow
|
1 there was overflow
|
||||||
|
@retval
|
||||||
0 no error or some other errors except overflow
|
0 no error or some other errors except overflow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1275,10 +1275,10 @@ static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Interpret field value as an integer but return the result as a string.
|
Interpret field value as an integer but return the result as a string.
|
||||||
|
|
||||||
This is used for printing bit_fields as numbers while debugging
|
This is used for printing bit_fields as numbers while debugging.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
|
String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
|
||||||
|
|
@ -1299,6 +1299,7 @@ String *Field::val_int_as_str(String *val_buffer, my_bool unsigned_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// This is used as a table name when the table structure is not set up
|
||||||
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg,
|
uchar null_bit_arg,
|
||||||
utype unireg_check_arg, const char *field_name_arg)
|
utype unireg_check_arg, const char *field_name_arg)
|
||||||
|
|
@ -1547,17 +1548,15 @@ void Field::make_field(Send_field *field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Conversion from decimal to longlong with checking overflow and
|
Conversion from decimal to longlong with checking overflow and
|
||||||
setting correct value (min/max) in case of overflow
|
setting correct value (min/max) in case of overflow.
|
||||||
|
|
||||||
SYNOPSIS
|
@param val value which have to be converted
|
||||||
Field::convert_decimal2longlong()
|
@param unsigned_flag type of integer in which we convert val
|
||||||
val value which have to be converted
|
@param err variable to pass error code
|
||||||
unsigned_flag type of integer in which we convert val
|
|
||||||
err variable to pass error code
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
value converted from val
|
value converted from val
|
||||||
*/
|
*/
|
||||||
longlong Field::convert_decimal2longlong(const my_decimal *val,
|
longlong Field::convert_decimal2longlong(const my_decimal *val,
|
||||||
|
|
@ -1591,19 +1590,18 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Storing decimal in integer fields.
|
Storing decimal in integer fields.
|
||||||
|
|
||||||
SYNOPSIS
|
@param val value for storing
|
||||||
Field_num::store_decimal()
|
|
||||||
val value for storing
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This method is used by all integer fields, real/decimal redefine it
|
This method is used by all integer fields, real/decimal redefine it
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 error
|
@retval
|
||||||
|
!=0 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_num::store_decimal(const my_decimal *val)
|
int Field_num::store_decimal(const my_decimal *val)
|
||||||
|
|
@ -1615,19 +1613,17 @@ int Field_num::store_decimal(const my_decimal *val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return decimal value of integer field
|
Return decimal value of integer field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param decimal_value buffer for storing decimal value
|
||||||
Field_num::val_decimal()
|
|
||||||
decimal_value buffer for storing decimal value
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This method is used by all integer fields, real/decimal redefine it
|
This method is used by all integer fields, real/decimal redefine it.
|
||||||
All longlong values fit in our decimal buffer which cal store 8*9=72
|
All longlong values fit in our decimal buffer which cal store 8*9=72
|
||||||
digits of integer number
|
digits of integer number
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
pointer to decimal buffer with value of field
|
pointer to decimal buffer with value of field
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1660,22 +1656,24 @@ void Field_num::make_field(Send_field *field)
|
||||||
field->decimals= dec;
|
field->decimals= dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Decimal representation of Field_str
|
Decimal representation of Field_str.
|
||||||
|
|
||||||
SYNOPSIS
|
@param d value for storing
|
||||||
Field_str::store_decimal()
|
|
||||||
d value for storing
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
Field_str is the base class for fields like Field_enum, Field_date and some
|
Field_str is the base class for fields like Field_enum,
|
||||||
similar. Some dates use fraction and also string value should be
|
Field_date and some similar. Some dates use fraction and also
|
||||||
converted to floating point value according our rules, so we use double
|
string value should be converted to floating point value according
|
||||||
to store value of decimal in string
|
our rules, so we use double to store value of decimal in string.
|
||||||
|
|
||||||
RETURN
|
@todo
|
||||||
|
use decimal2string?
|
||||||
|
|
||||||
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 error
|
@retval
|
||||||
|
!=0 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_str::store_decimal(const my_decimal *d)
|
int Field_str::store_decimal(const my_decimal *d)
|
||||||
|
|
@ -1748,11 +1746,11 @@ bool Field::get_time(MYSQL_TIME *ltime)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This is called when storing a date in a string
|
This is called when storing a date in a string.
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Needs to be changed if/when we want to support different time formats
|
Needs to be changed if/when we want to support different time formats.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
|
int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg)
|
||||||
|
|
@ -2374,9 +2372,9 @@ String *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
|
||||||
return val_ptr;
|
return val_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Should be able to handle at least the following fixed decimal formats:
|
Should be able to handle at least the following fixed decimal formats:
|
||||||
** 5.00 , -1.0, 05, -05, +5 with optional pre/end space
|
5.00 , -1.0, 05, -05, +5 with optional pre/end space
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_decimal::cmp(const uchar *a_ptr,const uchar *b_ptr)
|
int Field_decimal::cmp(const uchar *a_ptr,const uchar *b_ptr)
|
||||||
|
|
@ -2498,13 +2496,11 @@ int Field_new_decimal::reset(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Generate max/min decimal value in case of overflow.
|
Generate max/min decimal value in case of overflow.
|
||||||
|
|
||||||
SYNOPSIS
|
@param decimal_value buffer for value
|
||||||
Field_new_decimal::set_value_on_overflow();
|
@param sign sign of value which caused overflow
|
||||||
decimal_value buffer for value
|
|
||||||
sign sign of value which caused overflow
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
|
void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
|
||||||
|
|
@ -2523,21 +2519,19 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Store decimal value in the binary buffer
|
Store decimal value in the binary buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
Checks if decimal_value fits into field size.
|
||||||
store_value(const my_decimal *decimal_value)
|
If it does, stores the decimal in the buffer using binary format.
|
||||||
decimal_value my_decimal
|
Otherwise sets maximal number that can be stored in the field.
|
||||||
|
|
||||||
DESCRIPTION
|
@param decimal_value my_decimal
|
||||||
checks if decimal_value fits into field size.
|
|
||||||
if it does, stores the decimal in the buffer using binary format.
|
|
||||||
Otherwise sets maximal number that can be stored in the field.
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
@retval
|
||||||
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
||||||
|
|
@ -2646,6 +2640,12 @@ int Field_new_decimal::store(const char *from, uint length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Fix following when double2my_decimal when double2decimal
|
||||||
|
will return E_DEC_TRUNCATED always correctly
|
||||||
|
*/
|
||||||
|
|
||||||
int Field_new_decimal::store(double nr)
|
int Field_new_decimal::store(double nr)
|
||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
||||||
|
|
@ -4667,9 +4667,8 @@ void Field_double::sql_type(String &res) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TIMESTAMP type.
|
TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
|
||||||
Holds datetime values in range from 1970-01-01 00:00:01 UTC to
|
|
||||||
2038-01-01 00:00:00 UTC stored as number of seconds since Unix
|
2038-01-01 00:00:00 UTC stored as number of seconds since Unix
|
||||||
Epoch in UTC.
|
Epoch in UTC.
|
||||||
|
|
||||||
|
|
@ -4702,7 +4701,7 @@ void Field_double::sql_type(String &res) const
|
||||||
NONE - field which is not auto-set on update with some other than NOW()
|
NONE - field which is not auto-set on update with some other than NOW()
|
||||||
default value (TIMESTAMP DEFAULT 0).
|
default value (TIMESTAMP DEFAULT 0).
|
||||||
|
|
||||||
Note that TIMESTAMP_OLD_FIELD's are never created explicitly now, they are
|
Note that TIMESTAMP_OLD_FIELDs are never created explicitly now, they are
|
||||||
left only for preserving ability to read old tables. Such fields replaced
|
left only for preserving ability to read old tables. Such fields replaced
|
||||||
with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is
|
with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is
|
||||||
because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for
|
because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for
|
||||||
|
|
@ -4748,15 +4747,11 @@ Field_timestamp::Field_timestamp(bool maybe_null_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get auto-set type for TIMESTAMP field.
|
Get auto-set type for TIMESTAMP field.
|
||||||
|
|
||||||
SYNOPSIS
|
Returns value indicating during which operations this TIMESTAMP field
|
||||||
get_auto_set_type()
|
should be auto-set to current timestamp.
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Returns value indicating during which operations this TIMESTAMP field
|
|
||||||
should be auto-set to current timestamp.
|
|
||||||
*/
|
*/
|
||||||
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
|
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
|
||||||
{
|
{
|
||||||
|
|
@ -5239,7 +5234,8 @@ longlong Field_time::val_int(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@note
|
||||||
This function is multi-byte safe as the result string is always of type
|
This function is multi-byte safe as the result string is always of type
|
||||||
my_charset_bin
|
my_charset_bin
|
||||||
*/
|
*/
|
||||||
|
|
@ -5266,7 +5262,8 @@ String *Field_time::val_str(String *val_buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@note
|
||||||
Normally we would not consider 'time' as a valid date, but we allow
|
Normally we would not consider 'time' as a valid date, but we allow
|
||||||
get_date() here to be able to do things like
|
get_date() here to be able to do things like
|
||||||
DATE_FORMAT(time, "%l.%i %p")
|
DATE_FORMAT(time, "%l.%i %p")
|
||||||
|
|
@ -6385,15 +6382,12 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Store double value in Field_string or Field_varstring.
|
Store double value in Field_string or Field_varstring.
|
||||||
|
|
||||||
SYNOPSIS
|
Pretty prints double number into field_length characters buffer.
|
||||||
store(double nr)
|
|
||||||
nr number
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param nr number
|
||||||
Pretty prints double number into field_length characters buffer.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_str::store(double nr)
|
int Field_str::store(double nr)
|
||||||
|
|
@ -6801,18 +6795,18 @@ int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare a packed key against row
|
Compare a packed key against row.
|
||||||
|
|
||||||
SYNOPSIS
|
@param key Original key
|
||||||
pack_cmp()
|
@param length Key length. (May be less than field length)
|
||||||
key Original key
|
@param insert_or_update 1 if this is an insert or update
|
||||||
length Key length. (May be less than field length)
|
|
||||||
insert_or_update 1 if this is an insert or update
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
< 0 row < key
|
< 0 row < key
|
||||||
|
@return
|
||||||
0 row = key
|
0 row = key
|
||||||
|
@return
|
||||||
> 0 row > key
|
> 0 row > key
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -7056,8 +7050,9 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
NOTE: varstring and blob keys are ALWAYS stored with a 2 byte length prefix
|
@note
|
||||||
|
varstring and blob keys are ALWAYS stored with a 2 byte length prefix
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
|
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
|
||||||
|
|
@ -7077,10 +7072,10 @@ int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare to key segments (always 2 byte length prefix)
|
Compare to key segments (always 2 byte length prefix).
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This is used only to compare key segments created for index_read().
|
This is used only to compare key segments created for index_read().
|
||||||
(keys are created and compared in key.cc)
|
(keys are created and compared in key.cc)
|
||||||
*/
|
*/
|
||||||
|
|
@ -7200,21 +7195,18 @@ Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unpack a key into a record buffer.
|
Unpack a key into a record buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
A VARCHAR key has a maximum size of 64K-1.
|
||||||
unpack_key()
|
In its packed form, the length field is one or two bytes long,
|
||||||
to Pointer into the record buffer.
|
depending on 'max_length'.
|
||||||
key Pointer to the packed key.
|
|
||||||
max_length Key length limit from key description.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param to Pointer into the record buffer.
|
||||||
A VARCHAR key has a maximum size of 64K-1.
|
@param key Pointer to the packed key.
|
||||||
In its packed form, the length field is one or two bytes long,
|
@param max_length Key length limit from key description.
|
||||||
depending on 'max_length'.
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Pointer to end of 'key' (To the next key part if multi-segment key)
|
Pointer to end of 'key' (To the next key part if multi-segment key)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -7236,16 +7228,14 @@ Field_varstring::unpack_key(uchar *to, const uchar *key, uint max_length,
|
||||||
return key + length;
|
return key + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create a packed key that will be used for storage in the index tree
|
Create a packed key that will be used for storage in the index tree.
|
||||||
|
|
||||||
SYNOPSIS
|
@param to Store packed key segment here
|
||||||
pack_key_from_key_image()
|
@param from Key segment (as given to index_read())
|
||||||
to Store packed key segment here
|
@param max_length Max length of key
|
||||||
from Key segment (as given to index_read())
|
|
||||||
max_length Max length of key
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
end of key storage
|
end of key storage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -7579,21 +7569,15 @@ uint32 Field_blob::get_length(const uchar *pos, uint packlength_arg, bool low_by
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Put a blob length field into a record buffer.
|
Put a blob length field into a record buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
Depending on the maximum length of a blob, its length field is
|
||||||
Field_blob::put_length()
|
put into 1 to 4 bytes. This is a property of the blob object,
|
||||||
pos Pointer into the record buffer.
|
described by 'packlength'.
|
||||||
length The length value to put.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param pos Pointer into the record buffer.
|
||||||
Depending on the maximum length of a blob, its length field is
|
@param length The length value to put.
|
||||||
put into 1 to 4 bytes. This is a property of the blob object,
|
|
||||||
described by 'packlength'.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
nothing
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Field_blob::put_length(uchar *pos, uint32 length)
|
void Field_blob::put_length(uchar *pos, uint32 length)
|
||||||
|
|
@ -8094,7 +8078,7 @@ int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
|
||||||
insert_or_update);
|
insert_or_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a packed key that will be used for storage from a MySQL row */
|
/** Create a packed key that will be used for storage from a MySQL row. */
|
||||||
|
|
||||||
uchar *
|
uchar *
|
||||||
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
|
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
|
||||||
|
|
@ -8120,26 +8104,24 @@ Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unpack a blob key into a record buffer.
|
Unpack a blob key into a record buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
A blob key has a maximum size of 64K-1.
|
||||||
Field_blob::unpack_key()
|
In its packed form, the length field is one or two bytes long,
|
||||||
to Pointer into the record buffer.
|
depending on 'max_length'.
|
||||||
from Pointer to the packed key.
|
Depending on the maximum length of a blob, its length field is
|
||||||
max_length Key length limit from key description.
|
put into 1 to 4 bytes. This is a property of the blob object,
|
||||||
|
described by 'packlength'.
|
||||||
|
Blobs are internally stored apart from the record buffer, which
|
||||||
|
contains a pointer to the blob buffer.
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
A blob key has a maximum size of 64K-1.
|
|
||||||
In its packed form, the length field is one or two bytes long,
|
|
||||||
depending on 'max_length'.
|
|
||||||
Depending on the maximum length of a blob, its length field is
|
|
||||||
put into 1 to 4 bytes. This is a property of the blob object,
|
|
||||||
described by 'packlength'.
|
|
||||||
Blobs are internally stored apart from the record buffer, which
|
|
||||||
contains a pointer to the blob buffer.
|
|
||||||
|
|
||||||
RETURN
|
@param to Pointer into the record buffer.
|
||||||
|
@param from Pointer to the packed key.
|
||||||
|
@param max_length Key length limit from key description.
|
||||||
|
|
||||||
|
@return
|
||||||
Pointer into 'from' past the last byte copied from packed key.
|
Pointer into 'from' past the last byte copied from packed key.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -8166,7 +8148,7 @@ Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create a packed key that will be used for storage from a MySQL key */
|
/** Create a packed key that will be used for storage from a MySQL key. */
|
||||||
|
|
||||||
uchar *
|
uchar *
|
||||||
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
|
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
|
||||||
|
|
@ -8358,9 +8340,10 @@ void Field_enum::store_type(ulonglong value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Note. Storing a empty string in a enum field gives a warning
|
@note
|
||||||
** (if there isn't a empty value in the enum)
|
Storing a empty string in a enum field gives a warning
|
||||||
|
(if there isn't a empty value in the enum)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
|
|
@ -8686,7 +8669,12 @@ void Field_set::sql_type(String &res) const
|
||||||
res.append(')');
|
res.append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 1 if the fields are equally defined */
|
/**
|
||||||
|
@retval
|
||||||
|
1 if the fields are equally defined
|
||||||
|
@retval
|
||||||
|
0 if the fields are unequally defined
|
||||||
|
*/
|
||||||
|
|
||||||
bool Field::eq_def(Field *field)
|
bool Field::eq_def(Field *field)
|
||||||
{
|
{
|
||||||
|
|
@ -8696,6 +8684,10 @@ bool Field::eq_def(Field *field)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return
|
||||||
|
returns 1 if the fields are equally defined
|
||||||
|
*/
|
||||||
bool Field_enum::eq_def(Field *field)
|
bool Field_enum::eq_def(Field *field)
|
||||||
{
|
{
|
||||||
if (!Field::eq_def(field))
|
if (!Field::eq_def(field))
|
||||||
|
|
@ -8714,6 +8706,10 @@ bool Field_enum::eq_def(Field *field)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return
|
||||||
|
returns 1 if the fields are equally defined
|
||||||
|
*/
|
||||||
bool Field_num::eq_def(Field *field)
|
bool Field_num::eq_def(Field *field)
|
||||||
{
|
{
|
||||||
if (!Field::eq_def(field))
|
if (!Field::eq_def(field))
|
||||||
|
|
@ -9289,14 +9285,8 @@ void Field_bit_as_char::sql_type(String &res) const
|
||||||
Handling of field and Create_field
|
Handling of field and Create_field
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Convert Create_field::length from number of characters to number of bytes
|
Convert create_field::length from number of characters to number of bytes.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Create_field::create_length_to_internal_length()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Convert Create_field::length from number of characters to number of bytes.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Create_field::create_length_to_internal_length(void)
|
void Create_field::create_length_to_internal_length(void)
|
||||||
|
|
@ -9346,6 +9336,9 @@ void Create_field::create_length_to_internal_length(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Init for a tmp table field. To be extended if need be.
|
||||||
|
*/
|
||||||
void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
||||||
uint32 length_arg, uint32 decimals_arg,
|
uint32 length_arg, uint32 decimals_arg,
|
||||||
bool maybe_null, bool is_unsigned)
|
bool maybe_null, bool is_unsigned)
|
||||||
|
|
@ -9364,26 +9357,26 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize field definition for create
|
Initialize field definition for create.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handle
|
||||||
thd Thread handle
|
@param fld_name Field name
|
||||||
fld_name Field name
|
@param fld_type Field type
|
||||||
fld_type Field type
|
@param fld_length Field length
|
||||||
fld_length Field length
|
@param fld_decimals Decimal (if any)
|
||||||
fld_decimals Decimal (if any)
|
@param fld_type_modifier Additional type information
|
||||||
fld_type_modifier Additional type information
|
@param fld_default_value Field default value (if any)
|
||||||
fld_default_value Field default value (if any)
|
@param fld_on_update_value The value of ON UPDATE clause
|
||||||
fld_on_update_value The value of ON UPDATE clause
|
@param fld_comment Field comment
|
||||||
fld_comment Field comment
|
@param fld_change Field change
|
||||||
fld_change Field change
|
@param fld_interval_list Interval list (if any)
|
||||||
fld_interval_list Interval list (if any)
|
@param fld_charset Field charset
|
||||||
fld_charset Field charset
|
@param fld_geom_type Field geometry type (if any)
|
||||||
fld_geom_type Field geometry type (if any)
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE on success
|
FALSE on success
|
||||||
|
@retval
|
||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -9971,7 +9964,7 @@ Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create a field suitable for create of table */
|
/** Create a field suitable for create of table. */
|
||||||
|
|
||||||
Create_field::Create_field(Field *old_field,Field *orig_field)
|
Create_field::Create_field(Field *old_field,Field *orig_field)
|
||||||
{
|
{
|
||||||
|
|
@ -10059,13 +10052,10 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
maximum possible display length for blob
|
maximum possible display length for blob.
|
||||||
|
|
||||||
SYNOPSIS
|
@return
|
||||||
Field_blob::max_display_length()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
length
|
length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -10092,24 +10082,23 @@ uint32 Field_blob::max_display_length()
|
||||||
Warning handling
|
Warning handling
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Produce warning or note about data saved into field
|
Produce warning or note about data saved into field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param level - level of message (Note/Warning/Error)
|
||||||
set_warning()
|
@param code - error code of message to be produced
|
||||||
level - level of message (Note/Warning/Error)
|
@param cuted_increment - whenever we should increase cut fields count or not
|
||||||
code - error code of message to be produced
|
|
||||||
cuted_increment - whenever we should increase cut fields count or not
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This function won't produce warning and increase cut fields counter
|
This function won't produce warning and increase cut fields counter
|
||||||
if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
|
if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
|
||||||
|
|
||||||
if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
|
if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
|
||||||
This allows us to avoid notes in optimisation, like convert_constant_item().
|
This allows us to avoid notes in optimisation, like convert_constant_item().
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
|
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
|
||||||
|
@retval
|
||||||
0 otherwise
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -10133,21 +10122,19 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Produce warning or note about datetime string data saved into field
|
Produce warning or note about datetime string data saved into field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param level level of message (Note/Warning/Error)
|
||||||
set_datime_warning()
|
@param code error code of message to be produced
|
||||||
level - level of message (Note/Warning/Error)
|
@param str string value which we tried to save
|
||||||
code - error code of message to be produced
|
@param str_length length of string which we tried to save
|
||||||
str - string value which we tried to save
|
@param ts_type type of datetime value (datetime/date/time)
|
||||||
str_len - length of string which we tried to save
|
@param cuted_increment whenever we should increase cut fields count or not
|
||||||
ts_type - type of datetime value (datetime/date/time)
|
|
||||||
cuted_increment - whenever we should increase cut fields count or not
|
@note
|
||||||
|
This function will always produce some warning but won't increase cut
|
||||||
NOTE
|
fields counter if count_cuted_fields ==FIELD_CHECK_IGNORE for current
|
||||||
This function will always produce some warning but won't increase cut
|
|
||||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
|
||||||
thread.
|
thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -10165,20 +10152,18 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Produce warning or note about integer datetime value saved into field
|
Produce warning or note about integer datetime value saved into field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param level level of message (Note/Warning/Error)
|
||||||
set_warning()
|
@param code error code of message to be produced
|
||||||
level - level of message (Note/Warning/Error)
|
@param nr numeric value which we tried to save
|
||||||
code - error code of message to be produced
|
@param ts_type type of datetime value (datetime/date/time)
|
||||||
nr - numeric value which we tried to save
|
@param cuted_increment whenever we should increase cut fields count or not
|
||||||
ts_type - type of datetime value (datetime/date/time)
|
|
||||||
cuted_increment - whenever we should increase cut fields count or not
|
@note
|
||||||
|
This function will always produce some warning but won't increase cut
|
||||||
NOTE
|
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||||
This function will always produce some warning but won't increase cut
|
|
||||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
|
||||||
thread.
|
thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -10199,19 +10184,17 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Produce warning or note about double datetime data saved into field
|
Produce warning or note about double datetime data saved into field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param level level of message (Note/Warning/Error)
|
||||||
set_warning()
|
@param code error code of message to be produced
|
||||||
level - level of message (Note/Warning/Error)
|
@param nr double value which we tried to save
|
||||||
code - error code of message to be produced
|
@param ts_type type of datetime value (datetime/date/time)
|
||||||
nr - double value which we tried to save
|
|
||||||
ts_type - type of datetime value (datetime/date/time)
|
@note
|
||||||
|
This function will always produce some warning but won't increase cut
|
||||||
NOTE
|
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
||||||
This function will always produce some warning but won't increase cut
|
|
||||||
fields counter if count_cuted_fields == FIELD_CHECK_IGNORE for current
|
|
||||||
thread.
|
thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,15 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Functions to copy data to or from fields
|
@file
|
||||||
This could be done with a single short function but opencoding this
|
|
||||||
gives much more speed.
|
@brief
|
||||||
*/
|
Functions to copy data to or from fields
|
||||||
|
|
||||||
|
This could be done with a single short function but opencoding this
|
||||||
|
gives much more speed.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
|
@ -129,22 +133,21 @@ set_field_to_null(Field *field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set field to NULL or TIMESTAMP or to next auto_increment number
|
Set field to NULL or TIMESTAMP or to next auto_increment number.
|
||||||
|
|
||||||
SYNOPSIS
|
@param field Field to update
|
||||||
set_field_to_null_with_conversions()
|
@param no_conversions Set to 1 if we should return 1 if field can't
|
||||||
field Field to update
|
take null values.
|
||||||
no_conversion Set to 1 if we should return 1 if field can't
|
If set to 0 we will do store the 'default value'
|
||||||
take null values.
|
if the field is a special field. If not we will
|
||||||
If set to 0 we will do store the 'default value'
|
give an error.
|
||||||
if the field is a special field. If not we will
|
|
||||||
give an error.
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 Field could take 0 or an automatic conversion was used
|
0 Field could take 0 or an automatic conversion was used
|
||||||
-1 Field could not take NULL and no conversion was used.
|
@retval
|
||||||
If no_conversion was not set, an error message is printed
|
-1 Field could not take NULL and no conversion was used.
|
||||||
|
If no_conversion was not set, an error message is printed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -283,7 +286,7 @@ static void do_conv_blob(Copy_field *copy)
|
||||||
copy->tmp.charset());
|
copy->tmp.charset());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save blob in copy->tmp for GROUP BY */
|
/** Save blob in copy->tmp for GROUP BY. */
|
||||||
|
|
||||||
static void do_save_blob(Copy_field *copy)
|
static void do_save_blob(Copy_field *copy)
|
||||||
{
|
{
|
||||||
|
|
@ -352,9 +355,9 @@ static void do_field_decimal(Copy_field *copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
string copy for single byte characters set when to string is shorter than
|
string copy for single byte characters set when to string is shorter than
|
||||||
from string
|
from string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void do_cut_string(Copy_field *copy)
|
static void do_cut_string(Copy_field *copy)
|
||||||
|
|
@ -374,9 +377,9 @@ static void do_cut_string(Copy_field *copy)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
string copy for multi byte characters set when to string is shorter than
|
string copy for multi byte characters set when to string is shorter than
|
||||||
from string
|
from string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void do_cut_string_complex(Copy_field *copy)
|
static void do_cut_string_complex(Copy_field *copy)
|
||||||
|
|
@ -507,7 +510,7 @@ static void do_varstring2_mb(Copy_field *copy)
|
||||||
** The different functions that fills in a Copy_field class
|
** The different functions that fills in a Copy_field class
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
copy of field to maybe null string.
|
copy of field to maybe null string.
|
||||||
If field is null then the all bytes are set to 0.
|
If field is null then the all bytes are set to 0.
|
||||||
if field is not null then the first byte is set to 1 and the rest of the
|
if field is not null then the first byte is set to 1 and the rest of the
|
||||||
|
|
@ -748,7 +751,7 @@ Copy_field::get_copy_func(Field *to,Field *from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Simple quick field convert that is called on insert */
|
/** Simple quick field convert that is called on insert. */
|
||||||
|
|
||||||
int field_conv(Field *to,Field *from)
|
int field_conv(Field *to,Field *from)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
296
sql/filesort.cc
296
sql/filesort.cc
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Sorts a database */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Sorts a database
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#ifdef HAVE_STDDEF_H
|
#ifdef HAVE_STDDEF_H
|
||||||
|
|
@ -27,8 +32,7 @@
|
||||||
#define SKIP_DBUG_IN_FILESORT
|
#define SKIP_DBUG_IN_FILESORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* How to write record_ref. */
|
/// How to write record_ref.
|
||||||
|
|
||||||
#define WRITE_REF(file,from) \
|
#define WRITE_REF(file,from) \
|
||||||
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
if (my_b_write((file),(uchar*) (from),param->ref_length)) \
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
@ -58,42 +62,40 @@ static SORT_ADDON_FIELD *get_addon_fields(THD *thd, Field **ptabfield,
|
||||||
uint sortlength, uint *plength);
|
uint sortlength, uint *plength);
|
||||||
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
static void unpack_addon_fields(struct st_sort_addon_field *addon_field,
|
||||||
uchar *buff);
|
uchar *buff);
|
||||||
|
/**
|
||||||
|
Sort a table.
|
||||||
|
Creates a set of pointers that can be used to read the rows
|
||||||
|
in sorted order. This should be done with the functions
|
||||||
|
in records.cc.
|
||||||
|
|
||||||
/*
|
Before calling filesort, one must have done
|
||||||
Sort a table
|
table->file->info(HA_STATUS_VARIABLE)
|
||||||
|
|
||||||
SYNOPSIS
|
The result set is stored in table->io_cache or
|
||||||
filesort()
|
table->record_pointers.
|
||||||
table Table to sort
|
|
||||||
sortorder How to sort the table
|
@param thd Current thread
|
||||||
s_length Number of elements in sortorder
|
@param table Table to sort
|
||||||
select Condition to apply to the rows
|
@param sortorder How to sort the table
|
||||||
ha_maxrows Return only this many rows
|
@param s_length Number of elements in sortorder
|
||||||
sort_positions Set to 1 if we want to force sorting by position
|
@param select condition to apply to the rows
|
||||||
|
@param max_rows Return only this many rows
|
||||||
|
@param sort_positions Set to 1 if we want to force sorting by position
|
||||||
(Needed by UPDATE/INSERT or ALTER TABLE)
|
(Needed by UPDATE/INSERT or ALTER TABLE)
|
||||||
examined_rows Store number of examined rows here
|
@param examined_rows Store number of examined rows here
|
||||||
|
|
||||||
IMPLEMENTATION
|
@todo
|
||||||
Creates a set of pointers that can be used to read the rows
|
check why we do this (param.keys--)
|
||||||
in sorted order. This should be done with the functions
|
@note
|
||||||
in records.cc
|
|
||||||
|
|
||||||
REQUIREMENTS
|
|
||||||
Before calling filesort, one must have done
|
|
||||||
table->file->info(HA_STATUS_VARIABLE)
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
If we sort by position (like if sort_positions is 1) filesort() will
|
If we sort by position (like if sort_positions is 1) filesort() will
|
||||||
call table->prepare_for_position().
|
call table->prepare_for_position().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
HA_POS_ERROR Error
|
HA_POS_ERROR Error
|
||||||
# Number of rows
|
@retval
|
||||||
|
\# Number of rows
|
||||||
|
@retval
|
||||||
examined_rows will be set to number of examined rows
|
examined_rows will be set to number of examined rows
|
||||||
|
|
||||||
The result set is stored in table->io_cache or
|
|
||||||
table->record_pointers
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
||||||
|
|
@ -351,7 +353,7 @@ void filesort_free_buffers(TABLE *table, bool full)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make a array of string pointers */
|
/** Make a array of string pointers. */
|
||||||
|
|
||||||
static char **make_char_array(char **old_pos, register uint fields,
|
static char **make_char_array(char **old_pos, register uint fields,
|
||||||
uint length, myf my_flag)
|
uint length, myf my_flag)
|
||||||
|
|
@ -372,7 +374,7 @@ static char **make_char_array(char **old_pos, register uint fields,
|
||||||
} /* make_char_array */
|
} /* make_char_array */
|
||||||
|
|
||||||
|
|
||||||
/* Read 'count' number of buffer pointers into memory */
|
/** Read 'count' number of buffer pointers into memory. */
|
||||||
|
|
||||||
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||||
{
|
{
|
||||||
|
|
@ -395,38 +397,40 @@ static BUFFPEK *read_buffpek_from_file(IO_CACHE *buffpek_pointers, uint count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Search after sort_keys and write them into tempfile.
|
Search after sort_keys and write them into tempfile.
|
||||||
SYNOPSIS
|
All produced sequences are guaranteed to be non-empty.
|
||||||
find_all_keys()
|
|
||||||
param Sorting parameter
|
@param param Sorting parameter
|
||||||
select Use this to get source data
|
@param select Use this to get source data
|
||||||
sort_keys Array of pointers to sort key + addon buffers.
|
@param sort_keys Array of pointers to sort key + addon buffers.
|
||||||
buffpek_pointers File to write BUFFPEKs describing sorted segments
|
@param buffpek_pointers File to write BUFFPEKs describing sorted segments
|
||||||
in tempfile.
|
in tempfile.
|
||||||
tempfile File to write sorted sequences of sortkeys to.
|
@param tempfile File to write sorted sequences of sortkeys to.
|
||||||
indexfile If !NULL, use it for source data (contains rowids)
|
@param indexfile If !NULL, use it for source data (contains rowids)
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
Basic idea:
|
Basic idea:
|
||||||
while (get_next_sortkey())
|
@verbatim
|
||||||
{
|
while (get_next_sortkey())
|
||||||
if (no free space in sort_keys buffers)
|
{
|
||||||
{
|
if (no free space in sort_keys buffers)
|
||||||
sort sort_keys buffer;
|
{
|
||||||
dump sorted sequence to 'tempfile';
|
sort sort_keys buffer;
|
||||||
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
dump sorted sequence to 'tempfile';
|
||||||
}
|
dump BUFFPEK describing sequence location into 'buffpek_pointers';
|
||||||
put sort key into 'sort_keys';
|
}
|
||||||
}
|
put sort key into 'sort_keys';
|
||||||
if (sort_keys has some elements && dumped at least once)
|
}
|
||||||
sort-dump-dump as above;
|
if (sort_keys has some elements && dumped at least once)
|
||||||
else
|
sort-dump-dump as above;
|
||||||
don't sort, leave sort_keys array to be sorted by caller.
|
else
|
||||||
|
don't sort, leave sort_keys array to be sorted by caller.
|
||||||
All produced sequences are guaranteed to be non-empty.
|
@endverbatim
|
||||||
RETURN
|
|
||||||
|
@retval
|
||||||
Number of records written on success.
|
Number of records written on success.
|
||||||
|
@retval
|
||||||
HA_POS_ERROR on error.
|
HA_POS_ERROR on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -594,23 +598,25 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
||||||
} /* find_all_keys */
|
} /* find_all_keys */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Sort the buffer and write:
|
Sort the buffer and write:
|
||||||
1) the sorted sequence to tempfile
|
-# the sorted sequence to tempfile
|
||||||
2) a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
-# a BUFFPEK describing the sorted sequence position to buffpek_pointers
|
||||||
(was: Skriver en buffert med nycklar till filen)
|
|
||||||
SYNOPSIS
|
(was: Skriver en buffert med nycklar till filen)
|
||||||
write_keys()
|
|
||||||
param Sort parameters
|
@param param Sort parameters
|
||||||
sort_keys Array of pointers to keys to sort
|
@param sort_keys Array of pointers to keys to sort
|
||||||
count Number of elements in sort_keys array
|
@param count Number of elements in sort_keys array
|
||||||
buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
@param buffpek_pointers One 'BUFFPEK' struct will be written into this file.
|
||||||
The BUFFPEK::{file_pos, count} will indicate where
|
The BUFFPEK::{file_pos, count} will indicate where
|
||||||
the sorted data was stored.
|
the sorted data was stored.
|
||||||
tempfile The sorted sequence will be written into this file.
|
@param tempfile The sorted sequence will be written into this file.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 Error
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -653,8 +659,8 @@ err:
|
||||||
} /* write_keys */
|
} /* write_keys */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Store length as suffix in high-byte-first order
|
Store length as suffix in high-byte-first order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void store_length(uchar *to, uint length, uint pack_length)
|
static inline void store_length(uchar *to, uint length, uint pack_length)
|
||||||
|
|
@ -676,7 +682,7 @@ static inline void store_length(uchar *to, uint length, uint pack_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* makes a sort-key from record */
|
/** Make a sort-key from record. */
|
||||||
|
|
||||||
static void make_sortkey(register SORTPARAM *param,
|
static void make_sortkey(register SORTPARAM *param,
|
||||||
register uchar *to, uchar *ref_pos)
|
register uchar *to, uchar *ref_pos)
|
||||||
|
|
@ -990,7 +996,7 @@ static bool save_index(SORTPARAM *param, uchar **sort_keys, uint count,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Merge buffers to make < MERGEBUFF2 buffers */
|
/** Merge buffers to make < MERGEBUFF2 buffers. */
|
||||||
|
|
||||||
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
|
int merge_many_buff(SORTPARAM *param, uchar *sort_buffer,
|
||||||
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
BUFFPEK *buffpek, uint *maxbuffer, IO_CACHE *t_file)
|
||||||
|
|
@ -1043,8 +1049,12 @@ cleanup:
|
||||||
} /* merge_many_buff */
|
} /* merge_many_buff */
|
||||||
|
|
||||||
|
|
||||||
/* Read data to buffer */
|
/**
|
||||||
/* This returns (uint) -1 if something goes wrong */
|
Read data to buffer.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
(uint)-1 if something goes wrong
|
||||||
|
*/
|
||||||
|
|
||||||
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
||||||
uint rec_length)
|
uint rec_length)
|
||||||
|
|
@ -1066,15 +1076,15 @@ uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
|
||||||
} /* read_to_buffer */
|
} /* read_to_buffer */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Put all room used by freed buffer to use in adjacent buffer. Note, that
|
Put all room used by freed buffer to use in adjacent buffer.
|
||||||
we can't simply distribute memory evenly between all buffers, because
|
|
||||||
new areas must not overlap with old ones.
|
Note, that we can't simply distribute memory evenly between all buffers,
|
||||||
SYNOPSIS
|
because new areas must not overlap with old ones.
|
||||||
reuse_freed_buff()
|
|
||||||
queue IN list of non-empty buffers, without freed buffer
|
@param[in] queue list of non-empty buffers, without freed buffer
|
||||||
reuse IN empty buffer
|
@param[in] reuse empty buffer
|
||||||
key_length IN key length
|
@param[in] key_length key length
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
||||||
|
|
@ -1099,22 +1109,22 @@ void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Merge buffers to one buffer
|
Merge buffers to one buffer.
|
||||||
SYNOPSIS
|
|
||||||
merge_buffers()
|
|
||||||
param Sort parameter
|
|
||||||
from_file File with source data (BUFFPEKs point to this file)
|
|
||||||
to_file File to write the sorted result data.
|
|
||||||
sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
|
||||||
lastbuff OUT Store here BUFFPEK describing data written to to_file
|
|
||||||
Fb First element in source BUFFPEKs array
|
|
||||||
Tb Last element in source BUFFPEKs array
|
|
||||||
flag
|
|
||||||
|
|
||||||
RETURN
|
@param param Sort parameter
|
||||||
0 - OK
|
@param from_file File with source data (BUFFPEKs point to this file)
|
||||||
other - error
|
@param to_file File to write the sorted result data.
|
||||||
|
@param sort_buffer Buffer for data to store up to MERGEBUFF2 sort keys.
|
||||||
|
@param lastbuff OUT Store here BUFFPEK describing data written to to_file
|
||||||
|
@param Fb First element in source BUFFPEKs array
|
||||||
|
@param Tb Last element in source BUFFPEKs array
|
||||||
|
@param flag
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 OK
|
||||||
|
@retval
|
||||||
|
other error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||||
|
|
@ -1350,23 +1360,21 @@ static uint suffix_length(ulong string_length)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Calculate length of sort key
|
Calculate length of sort key.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
sortlength()
|
@param sortorder Order of items to sort
|
||||||
thd Thread handler
|
@param s_length Number of items to sort
|
||||||
sortorder Order of items to sort
|
@param[out] multi_byte_charset Set to 1 if we are using multi-byte charset
|
||||||
uint s_length Number of items to sort
|
(In which case we have to use strxnfrm())
|
||||||
multi_byte_charset (out)
|
|
||||||
Set to 1 if we are using multi-byte charset
|
|
||||||
(In which case we have to use strxnfrm())
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
sortorder->length is updated for each sort item
|
sortorder->length is updated for each sort item.
|
||||||
|
@n
|
||||||
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
sortorder->need_strxnfrm is set 1 if we have to use strxnfrm
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Total length of sort buffer in bytes
|
Total length of sort buffer in bytes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1453,33 +1461,31 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get descriptors of fields appended to sorted fields and
|
Get descriptors of fields appended to sorted fields and
|
||||||
calculate its total length
|
calculate its total length.
|
||||||
|
|
||||||
SYNOPSIS
|
The function first finds out what fields are used in the result set.
|
||||||
get_addon_fields()
|
Then it calculates the length of the buffer to store the values of
|
||||||
thd Current thread
|
these fields together with the value of sort values.
|
||||||
ptabfields Array of references to the table fields
|
If the calculated length is not greater than max_length_for_sort_data
|
||||||
sortlength Total length of sorted fields
|
the function allocates memory for an array of descriptors containing
|
||||||
plength out: Total length of appended fields
|
layouts for the values of the non-sorted fields in the buffer and
|
||||||
|
fills them.
|
||||||
|
|
||||||
DESCRIPTION
|
@param thd Current thread
|
||||||
The function first finds out what fields are used in the result set.
|
@param ptabfield Array of references to the table fields
|
||||||
Then it calculates the length of the buffer to store the values of
|
@param sortlength Total length of sorted fields
|
||||||
these fields together with the value of sort values.
|
@param[out] plength Total length of appended fields
|
||||||
If the calculated length is not greater than max_length_for_sort_data
|
|
||||||
the function allocates memory for an array of descriptors containing
|
|
||||||
layouts for the values of the non-sorted fields in the buffer and
|
|
||||||
fills them.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The null bits for the appended values are supposed to be put together
|
The null bits for the appended values are supposed to be put together
|
||||||
and stored the buffer just ahead of the value of the first field.
|
and stored the buffer just ahead of the value of the first field.
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
Pointer to the layout descriptors for the appended fields, if any
|
Pointer to the layout descriptors for the appended fields, if any
|
||||||
NULL - if we do not store field values with sort data.
|
@retval
|
||||||
|
NULL if we do not store field values with sort data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static SORT_ADDON_FIELD *
|
static SORT_ADDON_FIELD *
|
||||||
|
|
@ -1555,20 +1561,18 @@ get_addon_fields(THD *thd, Field **ptabfield, uint sortlength, uint *plength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Copy (unpack) values appended to sorted fields from a buffer back to
|
Copy (unpack) values appended to sorted fields from a buffer back to
|
||||||
their regular positions specified by the Field::ptr pointers.
|
their regular positions specified by the Field::ptr pointers.
|
||||||
|
|
||||||
SYNOPSIS
|
@param addon_field Array of descriptors for appended fields
|
||||||
unpack_addon_fields()
|
@param buff Buffer which to unpack the value from
|
||||||
addon_field Array of descriptors for appended fields
|
|
||||||
buff Buffer which to unpack the value from
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The function is supposed to be used only as a callback function
|
The function is supposed to be used only as a callback function
|
||||||
when getting field values for the sorted result set.
|
when getting field values for the sorted result set.
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
void.
|
void.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,11 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@details
|
||||||
|
@verbatim
|
||||||
The idea of presented algorithm see in
|
The idea of presented algorithm see in
|
||||||
"The Art of Computer Programming" by Donald E. Knuth
|
"The Art of Computer Programming" by Donald E. Knuth
|
||||||
Volume 3 "Sorting and searching"
|
Volume 3 "Sorting and searching"
|
||||||
|
|
@ -63,12 +66,14 @@ for optimization, link is the 16-bit index in 'symbols' or 'sql_functions'
|
||||||
or search-array..
|
or search-array..
|
||||||
|
|
||||||
So, we can read full search-structure as 32-bit word
|
So, we can read full search-structure as 32-bit word
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@todo
|
||||||
|
use instead to_upper_lex, special array
|
||||||
|
(substitute chars) without skip codes..
|
||||||
|
@todo
|
||||||
|
try use reverse order of comparing..
|
||||||
|
|
||||||
TODO:
|
|
||||||
1. use instead to_upper_lex, special array
|
|
||||||
(substitute chars) without skip codes..
|
|
||||||
2. try use reverse order of comparing..
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NO_YACC_SYMBOLS
|
#define NO_YACC_SYMBOLS
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
465
sql/handler.cc
465
sql/handler.cc
|
|
@ -199,8 +199,8 @@ handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Use other database handler if databasehandler is not compiled in
|
Use other database handler if databasehandler is not compiled in.
|
||||||
*/
|
*/
|
||||||
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
|
handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
|
||||||
bool no_substitute, bool report_error)
|
bool no_substitute, bool report_error)
|
||||||
|
|
@ -280,15 +280,13 @@ handler *get_ha_partition(partition_info *part_info)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Register handler error messages for use with my_error().
|
Register handler error messages for use with my_error().
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
ha_init_errors()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 Error
|
@retval
|
||||||
|
!=0 Error
|
||||||
*/
|
*/
|
||||||
static int ha_init_errors(void)
|
static int ha_init_errors(void)
|
||||||
{
|
{
|
||||||
|
|
@ -349,15 +347,13 @@ static int ha_init_errors(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Unregister handler error messages.
|
Unregister handler error messages.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
ha_finish_errors()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 OK
|
0 OK
|
||||||
!= 0 Error
|
@retval
|
||||||
|
!=0 Error
|
||||||
*/
|
*/
|
||||||
static int ha_finish_errors(void)
|
static int ha_finish_errors(void)
|
||||||
{
|
{
|
||||||
|
|
@ -567,8 +563,9 @@ static my_bool closecon_handlerton(THD *thd, plugin_ref plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
don't bother to rollback here, it's done already
|
@note
|
||||||
|
don't bother to rollback here, it's done already
|
||||||
*/
|
*/
|
||||||
void ha_close_connection(THD* thd)
|
void ha_close_connection(THD* thd)
|
||||||
{
|
{
|
||||||
|
|
@ -578,17 +575,16 @@ void ha_close_connection(THD* thd)
|
||||||
/* ========================================================================
|
/* ========================================================================
|
||||||
======================= TRANSACTIONS ===================================*/
|
======================= TRANSACTIONS ===================================*/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Register a storage engine for a transaction
|
Register a storage engine for a transaction.
|
||||||
|
|
||||||
DESCRIPTION
|
Every storage engine MUST call this function when it starts
|
||||||
Every storage engine MUST call this function when it starts
|
a transaction or a statement (that is it must be called both for the
|
||||||
a transaction or a statement (that is it must be called both for the
|
"beginning of transaction" and "beginning of statement").
|
||||||
"beginning of transaction" and "beginning of statement").
|
Only storage engines registered for the transaction/statement
|
||||||
Only storage engines registered for the transaction/statement
|
will know when to commit/rollback it.
|
||||||
will know when to commit/rollback it.
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
trans_register_ha is idempotent - storage engine may register many
|
trans_register_ha is idempotent - storage engine may register many
|
||||||
times per transaction.
|
times per transaction.
|
||||||
|
|
||||||
|
|
@ -620,10 +616,11 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
RETURN
|
@retval
|
||||||
0 - ok
|
0 ok
|
||||||
1 - error, transaction was rolled back
|
@retval
|
||||||
|
1 error, transaction was rolled back
|
||||||
*/
|
*/
|
||||||
int ha_prepare(THD *thd)
|
int ha_prepare(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -660,11 +657,19 @@ int ha_prepare(THD *thd)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
RETURN
|
@retval
|
||||||
0 - ok
|
0 ok
|
||||||
1 - transaction was rolled back
|
@retval
|
||||||
2 - error during commit, data may be inconsistent
|
1 transaction was rolled back
|
||||||
|
@retval
|
||||||
|
2 error during commit, data may be inconsistent
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Since we don't support nested statement transactions in 5.0,
|
||||||
|
we can't commit or rollback stmt transactions while we are inside
|
||||||
|
stored functions or triggers. So we simply do nothing now.
|
||||||
|
TODO: This should be fixed in later ( >= 5.1) releases.
|
||||||
*/
|
*/
|
||||||
int ha_commit_trans(THD *thd, bool all)
|
int ha_commit_trans(THD *thd, bool all)
|
||||||
{
|
{
|
||||||
|
|
@ -757,9 +762,9 @@ end:
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
NOTE - this function does not care about global read lock.
|
@note
|
||||||
A caller should.
|
This function does not care about global read lock. A caller should.
|
||||||
*/
|
*/
|
||||||
int ha_commit_one_phase(THD *thd, bool all)
|
int ha_commit_one_phase(THD *thd, bool all)
|
||||||
{
|
{
|
||||||
|
|
@ -869,13 +874,16 @@ int ha_rollback_trans(THD *thd, bool all)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
This is used to commit or rollback a single statement depending on the value
|
This is used to commit or rollback a single statement depending on
|
||||||
of error. Note that if the autocommit is on, then the following call inside
|
the value of error.
|
||||||
InnoDB will commit or rollback the whole transaction (= the statement). The
|
|
||||||
autocommit mechanism built into InnoDB is based on counting locks, but if
|
@note
|
||||||
the user has used LOCK TABLES then that mechanism does not know to do the
|
Note that if the autocommit is on, then the following call inside
|
||||||
commit.
|
InnoDB will commit or rollback the whole transaction (= the statement). The
|
||||||
|
autocommit mechanism built into InnoDB is based on counting locks, but if
|
||||||
|
the user has used LOCK TABLES then that mechanism does not know to do the
|
||||||
|
commit.
|
||||||
*/
|
*/
|
||||||
int ha_autocommit_or_rollback(THD *thd, int error)
|
int ha_autocommit_or_rollback(THD *thd, int error)
|
||||||
{
|
{
|
||||||
|
|
@ -944,7 +952,10 @@ int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
|
||||||
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
/* this does not need to be multi-byte safe or anything */
|
/**
|
||||||
|
@note
|
||||||
|
This does not need to be multi-byte safe or anything
|
||||||
|
*/
|
||||||
static char* xid_to_str(char *buf, XID *xid)
|
static char* xid_to_str(char *buf, XID *xid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -996,24 +1007,21 @@ static char* xid_to_str(char *buf, XID *xid)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
recover() step of xa
|
recover() step of xa.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
there are three modes of operation:
|
there are three modes of operation:
|
||||||
|
- automatic recover after a crash
|
||||||
- automatic recover after a crash
|
in this case commit_list != 0, tc_heuristic_recover==0
|
||||||
in this case commit_list != 0, tc_heuristic_recover==0
|
all xids from commit_list are committed, others are rolled back
|
||||||
all xids from commit_list are committed, others are rolled back
|
- manual (heuristic) recover
|
||||||
|
in this case commit_list==0, tc_heuristic_recover != 0
|
||||||
- manual (heuristic) recover
|
DBA has explicitly specified that all prepared transactions should
|
||||||
in this case commit_list==0, tc_heuristic_recover != 0
|
be committed (or rolled back).
|
||||||
DBA has explicitly specified that all prepared transactions should
|
- no recovery (MySQL did not detect a crash)
|
||||||
be committed (or rolled back).
|
in this case commit_list==0, tc_heuristic_recover == 0
|
||||||
|
there should be no prepared transactions in this case.
|
||||||
- no recovery (MySQL did not detect a crash)
|
|
||||||
in this case commit_list==0, tc_heuristic_recover == 0
|
|
||||||
there should be no prepared transactions in this case.
|
|
||||||
*/
|
*/
|
||||||
struct xarecover_st
|
struct xarecover_st
|
||||||
{
|
{
|
||||||
|
|
@ -1146,10 +1154,10 @@ int ha_recover(HASH *commit_list)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
return the list of XID's to a client, the same way SHOW commands do
|
return the list of XID's to a client, the same way SHOW commands do.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
I didn't find in XA specs that an RM cannot return the same XID twice,
|
I didn't find in XA specs that an RM cannot return the same XID twice,
|
||||||
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
so mysql_xa_recover does not filter XID's to ensure uniqueness.
|
||||||
It can be easily fixed later, if necessary.
|
It can be easily fixed later, if necessary.
|
||||||
|
|
@ -1195,7 +1203,8 @@ bool mysql_xa_recover(THD *thd)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
|
@details
|
||||||
This function should be called when MySQL sends rows of a SELECT result set
|
This function should be called when MySQL sends rows of a SELECT result set
|
||||||
or the EOF mark to the client. It releases a possible adaptive hash index
|
or the EOF mark to the client. It releases a possible adaptive hash index
|
||||||
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
||||||
|
|
@ -1207,9 +1216,10 @@ bool mysql_xa_recover(THD *thd)
|
||||||
performs another SQL query. In MySQL-4.1 this is even more important because
|
performs another SQL query. In MySQL-4.1 this is even more important because
|
||||||
there a connection can have several SELECT queries open at the same time.
|
there a connection can have several SELECT queries open at the same time.
|
||||||
|
|
||||||
arguments:
|
@param thd the thread handle of the current connection
|
||||||
thd: the thread handle of the current connection
|
|
||||||
return value: always 0
|
@return
|
||||||
|
always 0
|
||||||
*/
|
*/
|
||||||
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
static my_bool release_temporary_latches(THD *thd, plugin_ref plugin,
|
||||||
void *unused)
|
void *unused)
|
||||||
|
|
@ -1276,8 +1286,9 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
note, that according to the sql standard (ISO/IEC 9075-2:2003)
|
@note
|
||||||
|
according to the sql standard (ISO/IEC 9075-2:2003)
|
||||||
section "4.33.4 SQL-statements and transaction states",
|
section "4.33.4 SQL-statements and transaction states",
|
||||||
SAVEPOINT is *not* transaction-initiating SQL-statement
|
SAVEPOINT is *not* transaction-initiating SQL-statement
|
||||||
*/
|
*/
|
||||||
|
|
@ -1593,8 +1604,9 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read first row (only) from a table
|
Read first row (only) from a table.
|
||||||
|
|
||||||
This is never called for InnoDB tables, as these table types
|
This is never called for InnoDB tables, as these table types
|
||||||
has the HA_STATS_RECORDS_IS_EXACT set.
|
has the HA_STATS_RECORDS_IS_EXACT set.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1627,16 +1639,16 @@ int handler::read_first_row(uchar * buf, uint primary_key)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Generate the next auto-increment number based on increment and offset:
|
Generate the next auto-increment number based on increment and offset.
|
||||||
computes the lowest number
|
computes the lowest number
|
||||||
- strictly greater than "nr"
|
- strictly greater than "nr"
|
||||||
- of the form: auto_increment_offset + N * auto_increment_increment
|
- of the form: auto_increment_offset + N * auto_increment_increment
|
||||||
|
|
||||||
In most cases increment= offset= 1, in which case we get:
|
In most cases increment= offset= 1, in which case we get:
|
||||||
1,2,3,4,5,...
|
@verbatim 1,2,3,4,5,... @endverbatim
|
||||||
If increment=10 and offset=5 and previous number is 1, we get:
|
If increment=10 and offset=5 and previous number is 1, we get:
|
||||||
1,5,15,25,35,...
|
@verbatim 1,5,15,25,35,... @endverbatim
|
||||||
*/
|
*/
|
||||||
inline ulonglong
|
inline ulonglong
|
||||||
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
|
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
|
||||||
|
|
@ -1702,23 +1714,10 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update the auto_increment field if necessary
|
Update the auto_increment field if necessary.
|
||||||
|
|
||||||
SYNOPSIS
|
Updates columns with type NEXT_NUMBER if:
|
||||||
update_auto_increment()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
|
||||||
HA_ERR_AUTOINC_READ_FAILED
|
|
||||||
get_auto_increment() was called and returned ~(ulonglong) 0
|
|
||||||
HA_ERR_AUTOINC_ERANGE
|
|
||||||
storing value in field caused strict mode failure.
|
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
|
|
||||||
Updates the record's Field of type NEXT_NUMBER if:
|
|
||||||
|
|
||||||
- If column value is set to NULL (in which case
|
- If column value is set to NULL (in which case
|
||||||
auto_increment_field_not_null is 0)
|
auto_increment_field_not_null is 0)
|
||||||
|
|
@ -1769,13 +1768,20 @@ prev_insert_id(ulonglong nr, struct system_variables *variables)
|
||||||
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
|
present in thd->auto_inc_intervals_in_cur_stmt_for_binlog it is added to
|
||||||
this list.
|
this list.
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
|
|
||||||
Replace all references to "next number" or NEXT_NUMBER to
|
Replace all references to "next number" or NEXT_NUMBER to
|
||||||
"auto_increment", everywhere (see below: there is
|
"auto_increment", everywhere (see below: there is
|
||||||
table->auto_increment_field_not_null, and there also exists
|
table->auto_increment_field_not_null, and there also exists
|
||||||
table->next_number_field, it's not consistent).
|
table->next_number_field, it's not consistent).
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 ok
|
||||||
|
@retval
|
||||||
|
HA_ERR_AUTOINC_READ_FAILED get_auto_increment() was called and
|
||||||
|
returned ~(ulonglong) 0
|
||||||
|
@retval
|
||||||
|
HA_ERR_AUTOINC_ERANGE storing value in field caused strict mode
|
||||||
|
failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
|
#define AUTO_INC_DEFAULT_NB_ROWS 1 // Some prefer 1024 here
|
||||||
|
|
@ -2079,14 +2085,14 @@ void handler::print_keydup_error(uint key_nr, const char *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Print error that we got from handler function
|
Print error that we got from handler function.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
In case of delete table it's only safe to use the following parts of
|
In case of delete table it's only safe to use the following parts of
|
||||||
the 'table' structure:
|
the 'table' structure:
|
||||||
table->s->path
|
- table->s->path
|
||||||
table->alias
|
- table->alias
|
||||||
*/
|
*/
|
||||||
void handler::print_error(int error, myf errflag)
|
void handler::print_error(int error, myf errflag)
|
||||||
{
|
{
|
||||||
|
|
@ -2273,14 +2279,14 @@ void handler::print_error(int error, myf errflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Return an error message specific to this handler
|
Return an error message specific to this handler.
|
||||||
|
|
||||||
SYNOPSIS
|
@param error error code previously returned by handler
|
||||||
error error code previously returned by handler
|
@param buf pointer to String where to add error message
|
||||||
buf Pointer to String where to add error message
|
|
||||||
|
|
||||||
Returns true if this is a temporary error
|
@return
|
||||||
|
Returns true if this is a temporary error
|
||||||
*/
|
*/
|
||||||
bool handler::get_error_message(int error, String* buf)
|
bool handler::get_error_message(int error, String* buf)
|
||||||
{
|
{
|
||||||
|
|
@ -2387,8 +2393,10 @@ err:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Return key if error because of duplicated keys */
|
@return
|
||||||
|
key if error because of duplicated keys
|
||||||
|
*/
|
||||||
uint handler::get_dup_key(int error)
|
uint handler::get_dup_key(int error)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("handler::get_dup_key");
|
DBUG_ENTER("handler::get_dup_key");
|
||||||
|
|
@ -2401,21 +2409,20 @@ uint handler::get_dup_key(int error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Delete all files with extension from bas_ext()
|
Delete all files with extension from bas_ext().
|
||||||
|
|
||||||
SYNOPSIS
|
@param name Base name of table
|
||||||
delete_table()
|
|
||||||
name Base name of table
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
We assume that the handler may return more extensions than
|
We assume that the handler may return more extensions than
|
||||||
was actually used for the file.
|
was actually used for the file.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 If we successfully deleted at least one file from base_ext and
|
0 If we successfully deleted at least one file from base_ext and
|
||||||
didn't get any other errors than ENOENT
|
didn't get any other errors than ENOENT
|
||||||
# Error
|
@retval
|
||||||
|
!0 Error
|
||||||
*/
|
*/
|
||||||
int handler::delete_table(const char *name)
|
int handler::delete_table(const char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -2462,21 +2469,20 @@ void handler::drop_table(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Performs checks upon the table.
|
Performs checks upon the table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread doing CHECK TABLE operation
|
||||||
check()
|
@param check_opt options from the parser
|
||||||
thd thread doing CHECK TABLE operation
|
|
||||||
check_opt options from the parser
|
|
||||||
|
|
||||||
NOTES
|
@retval
|
||||||
|
HA_ADMIN_OK Successful upgrade
|
||||||
RETURN
|
@retval
|
||||||
HA_ADMIN_OK Successful upgrade
|
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
||||||
HA_ADMIN_NEEDS_UPGRADE Table has structures requiring upgrade
|
@retval
|
||||||
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
HA_ADMIN_NEEDS_ALTER Table has structures requiring ALTER TABLE
|
||||||
HA_ADMIN_NOT_IMPLEMENTED
|
@retval
|
||||||
|
HA_ADMIN_NOT_IMPLEMENTED
|
||||||
*/
|
*/
|
||||||
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
|
||||||
{
|
{
|
||||||
|
|
@ -2511,7 +2517,7 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Tell the storage engine that it is allowed to "disable transaction" in the
|
Tell the storage engine that it is allowed to "disable transaction" in the
|
||||||
handler. It is a hint that ACID is not required - it is used in NDB for
|
handler. It is a hint that ACID is not required - it is used in NDB for
|
||||||
ALTER TABLE, for example, when data are copied to temporary table.
|
ALTER TABLE, for example, when data are copied to temporary table.
|
||||||
|
|
@ -2620,15 +2626,12 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||||
** Some general functions that isn't in the handler class
|
** Some general functions that isn't in the handler class
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Initiates table-file and calls appropriate database-creator
|
Initiates table-file and calls appropriate database-creator.
|
||||||
|
|
||||||
NOTES
|
@retval
|
||||||
We must have a write lock on LOCK_open to be sure no other thread
|
|
||||||
interferes with table
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
int ha_create_table(THD *thd, const char *path,
|
int ha_create_table(THD *thd, const char *path,
|
||||||
|
|
@ -2666,17 +2669,18 @@ err:
|
||||||
DBUG_RETURN(error != 0);
|
DBUG_RETURN(error != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Try to discover table from engine
|
Try to discover table from engine.
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If found, write the frm file to disk.
|
If found, write the frm file to disk.
|
||||||
|
|
||||||
RETURN VALUES:
|
@retval
|
||||||
-1 Table did not exists
|
-1 Table did not exists
|
||||||
|
@retval
|
||||||
0 Table created ok
|
0 Table created ok
|
||||||
|
@retval
|
||||||
> 0 Error, table existed but could not be created
|
> 0 Error, table existed but could not be created
|
||||||
|
|
||||||
*/
|
*/
|
||||||
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
|
int ha_create_table_from_engine(THD* thd, const char *db, const char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -2747,8 +2751,8 @@ void st_ha_check_opt::init()
|
||||||
call to ha_init_key_cache() (probably out of memory)
|
call to ha_init_key_cache() (probably out of memory)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Init a key cache if it has not been initied before
|
Init a key cache if it has not been initied before.
|
||||||
*/
|
*/
|
||||||
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
|
|
@ -2771,8 +2775,8 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Resize key cache
|
Resize key cache.
|
||||||
*/
|
*/
|
||||||
int ha_resize_key_cache(KEY_CACHE *key_cache)
|
int ha_resize_key_cache(KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
|
|
@ -2794,7 +2798,7 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Change parameters for key cache (like size)
|
Change parameters for key cache (like size)
|
||||||
*/
|
*/
|
||||||
int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
||||||
|
|
@ -2810,8 +2814,8 @@ int ha_change_key_cache_param(KEY_CACHE *key_cache)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Free memory allocated by a key cache
|
Free memory allocated by a key cache.
|
||||||
*/
|
*/
|
||||||
int ha_end_key_cache(KEY_CACHE *key_cache)
|
int ha_end_key_cache(KEY_CACHE *key_cache)
|
||||||
{
|
{
|
||||||
|
|
@ -2819,8 +2823,8 @@ int ha_end_key_cache(KEY_CACHE *key_cache)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Move all tables from one key cache to another one
|
Move all tables from one key cache to another one.
|
||||||
*/
|
*/
|
||||||
int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
||||||
KEY_CACHE *new_key_cache)
|
KEY_CACHE *new_key_cache)
|
||||||
|
|
@ -2830,13 +2834,15 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Try to discover one table from handler(s)
|
Try to discover one table from handler(s).
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
-1 : Table did not exists
|
-1 Table did not exists
|
||||||
0 : OK. In this case *frmblob and *frmlen are set
|
@retval
|
||||||
>0 : error. frmblob and frmlen may not be set
|
0 OK. In this case *frmblob and *frmlen are set
|
||||||
|
@retval
|
||||||
|
>0 error. frmblob and frmlen may not be set
|
||||||
*/
|
*/
|
||||||
struct st_discover_args
|
struct st_discover_args
|
||||||
{
|
{
|
||||||
|
|
@ -2881,9 +2887,9 @@ int ha_discover(THD *thd, const char *db, const char *name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Call this function in order to give the handler the possibility
|
Call this function in order to give the handler the possiblity
|
||||||
to ask engine if there are any new tables that should be written to disk
|
to ask engine if there are any new tables that should be written to disk
|
||||||
or any dropped tables that need to be removed from disk
|
or any dropped tables that need to be removed from disk
|
||||||
*/
|
*/
|
||||||
struct st_find_files_args
|
struct st_find_files_args
|
||||||
|
|
@ -2926,16 +2932,15 @@ ha_find_files(THD *thd,const char *db,const char *path,
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Ask handler if the table exists in engine
|
Ask handler if the table exists in engine.
|
||||||
|
@retval
|
||||||
RETURN
|
|
||||||
HA_ERR_NO_SUCH_TABLE Table does not exist
|
HA_ERR_NO_SUCH_TABLE Table does not exist
|
||||||
|
@retval
|
||||||
HA_ERR_TABLE_EXIST Table exists
|
HA_ERR_TABLE_EXIST Table exists
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct st_table_exists_in_engine_args
|
struct st_table_exists_in_engine_args
|
||||||
{
|
{
|
||||||
const char *db;
|
const char *db;
|
||||||
|
|
@ -3110,29 +3115,29 @@ void ha_binlog_log_query(THD *thd, handlerton *hton,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read the first row of a multi-range set.
|
Read the first row of a multi-range set.
|
||||||
|
|
||||||
SYNOPSIS
|
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||||
read_multi_range_first()
|
corresponds to the returned row.
|
||||||
found_range_p Returns a pointer to the element in 'ranges' that
|
@param ranges An array of KEY_MULTI_RANGE range descriptions.
|
||||||
corresponds to the returned row.
|
@param range_count Number of ranges in 'ranges'.
|
||||||
ranges An array of KEY_MULTI_RANGE range descriptions.
|
@param sorted If result should be sorted per key.
|
||||||
range_count Number of ranges in 'ranges'.
|
@param buffer A HANDLER_BUFFER for internal handler usage.
|
||||||
sorted If result should be sorted per key.
|
|
||||||
buffer A HANDLER_BUFFER for internal handler usage.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0].
|
- Record is read into table->record[0].
|
||||||
*found_range_p returns a valid value only if read_multi_range_first()
|
- *found_range_p returns a valid value only if read_multi_range_first()
|
||||||
returns 0.
|
returns 0.
|
||||||
Sorting is done within each range. If you want an overall sort, enter
|
- Sorting is done within each range. If you want an overall sort, enter
|
||||||
'ranges' with sorted ranges.
|
'ranges' with sorted ranges.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK, found a row
|
0 OK, found a row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||||
KEY_MULTI_RANGE *ranges, uint range_count,
|
KEY_MULTI_RANGE *ranges, uint range_count,
|
||||||
|
|
@ -3166,23 +3171,23 @@ int handler::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read the next row of a multi-range set.
|
Read the next row of a multi-range set.
|
||||||
|
|
||||||
SYNOPSIS
|
@param found_range_p Returns a pointer to the element in 'ranges' that
|
||||||
read_multi_range_next()
|
corresponds to the returned row.
|
||||||
found_range_p Returns a pointer to the element in 'ranges' that
|
|
||||||
corresponds to the returned row.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0].
|
- Record is read into table->record[0].
|
||||||
*found_range_p returns a valid value only if read_multi_range_next()
|
- *found_range_p returns a valid value only if read_multi_range_next()
|
||||||
returns 0.
|
returns 0.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK, found a row
|
0 OK, found a row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No (more) rows in range
|
HA_ERR_END_OF_FILE No (more) rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
|
||||||
{
|
{
|
||||||
|
|
@ -3238,25 +3243,24 @@ scan_it_again:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read first row between two ranges.
|
Read first row between two ranges.
|
||||||
Store ranges for future calls to read_range_next
|
Store ranges for future calls to read_range_next.
|
||||||
|
|
||||||
SYNOPSIS
|
@param start_key Start key. Is 0 if no min range
|
||||||
read_range_first()
|
@param end_key End key. Is 0 if no max range
|
||||||
start_key Start key. Is 0 if no min range
|
@param eq_range_arg Set to 1 if start_key == end_key
|
||||||
end_key End key. Is 0 if no max range
|
@param sorted Set to 1 if result should be sorted per key
|
||||||
eq_range_arg Set to 1 if start_key == end_key and the range endpoints
|
|
||||||
will not change during query execution.
|
|
||||||
sorted Set to 1 if result should be sorted per key
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Record is read into table->record[0]
|
Record is read into table->record[0]
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Found row
|
0 Found row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_range_first(const key_range *start_key,
|
int handler::read_range_first(const key_range *start_key,
|
||||||
const key_range *end_key,
|
const key_range *end_key,
|
||||||
|
|
@ -3292,19 +3296,18 @@ int handler::read_range_first(const key_range *start_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Read next row between two ranges.
|
Read next row between two ranges.
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
read_range_next()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
Record is read into table->record[0]
|
Record is read into table->record[0]
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Found row
|
0 Found row
|
||||||
|
@retval
|
||||||
HA_ERR_END_OF_FILE No rows in range
|
HA_ERR_END_OF_FILE No rows in range
|
||||||
# Error code
|
@retval
|
||||||
|
\# Error code
|
||||||
*/
|
*/
|
||||||
int handler::read_range_next()
|
int handler::read_range_next()
|
||||||
{
|
{
|
||||||
|
|
@ -3325,22 +3328,20 @@ int handler::read_range_next()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Compare if found key (in row) is over max-value
|
Compare if found key (in row) is over max-value.
|
||||||
|
|
||||||
SYNOPSIS
|
@param range range to compare to row. May be 0 for no range
|
||||||
compare_key
|
|
||||||
range range to compare to row. May be 0 for no range
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
See key.cc::key_cmp() for details
|
|
||||||
|
|
||||||
RETURN
|
@seealso
|
||||||
|
key.cc::key_cmp()
|
||||||
|
|
||||||
|
@return
|
||||||
The return value is SIGN(key_in_row - range_key):
|
The return value is SIGN(key_in_row - range_key):
|
||||||
|
|
||||||
0 Key is equal to range or 'range' == 0 (no range)
|
- 0 : Key is equal to range or 'range' == 0 (no range)
|
||||||
-1 Key is less than range
|
- -1 : Key is less than range
|
||||||
1 Key is larger than range
|
- 1 : Key is larger than range
|
||||||
*/
|
*/
|
||||||
int handler::compare_key(key_range *range)
|
int handler::compare_key(key_range *range)
|
||||||
{
|
{
|
||||||
|
|
@ -3369,18 +3370,14 @@ int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief
|
/**
|
||||||
Returns a list of all known extensions.
|
Returns a list of all known extensions.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
ha_known_exts()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
No mutexes, worst case race is a minor surplus memory allocation
|
No mutexes, worst case race is a minor surplus memory allocation
|
||||||
We have to recreate the extension map if mysqld is restarted (for example
|
We have to recreate the extension map if mysqld is restarted (for example
|
||||||
within libmysqld)
|
within libmysqld)
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
pointer pointer to TYPELIB structure
|
pointer pointer to TYPELIB structure
|
||||||
*/
|
*/
|
||||||
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
static my_bool exts_handlerton(THD *unused, plugin_ref plugin,
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,14 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get hostname for an IP. Hostnames are checked with reverse name lookup and
|
@file
|
||||||
checked that they doesn't resemble an ip.
|
|
||||||
|
@brief
|
||||||
|
Get hostname for an IP.
|
||||||
|
|
||||||
|
Hostnames are checked with reverse name lookup and
|
||||||
|
checked that they doesn't resemble an ip.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Init and dummy functions for interface with unireg */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Init and dummy functions for interface with unireg
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
|
|
||||||
998
sql/item.cc
998
sql/item.cc
File diff suppressed because it is too large
Load diff
|
|
@ -14,12 +14,17 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Buffers to save and compare item values */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Buffers to save and compare item values
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Create right type of Cached_item for an item
|
Create right type of Cached_item for an item.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Cached_item *new_Cached_item(THD *thd, Item *item)
|
Cached_item *new_Cached_item(THD *thd, Item *item)
|
||||||
|
|
@ -45,9 +50,11 @@ Cached_item *new_Cached_item(THD *thd, Item *item)
|
||||||
|
|
||||||
Cached_item::~Cached_item() {}
|
Cached_item::~Cached_item() {}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Compare with old value and replace value with new value
|
Compare with old value and replace value with new value.
|
||||||
** Return true if values have changed
|
|
||||||
|
@return
|
||||||
|
Return true if values have changed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all compare functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all compare functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -104,7 +109,7 @@ static int cmp_row_type(Item* item1, Item* item2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Aggregates result types from the array of items.
|
Aggregates result types from the array of items.
|
||||||
|
|
||||||
SYNOPSIS:
|
SYNOPSIS:
|
||||||
|
|
@ -117,11 +122,13 @@ static int cmp_row_type(Item* item1, Item* item2)
|
||||||
This function aggregates result types from the array of items. Found type
|
This function aggregates result types from the array of items. Found type
|
||||||
supposed to be used later for comparison of values of these items.
|
supposed to be used later for comparison of values of these items.
|
||||||
Aggregation itself is performed by the item_cmp_type() function.
|
Aggregation itself is performed by the item_cmp_type() function.
|
||||||
The function also checks compatibility of row signatures for the
|
@param[out] type the aggregated type
|
||||||
submitted items (see the spec for the cmp_row_type function).
|
@param items array of items to aggregate the type from
|
||||||
|
@param nitems number of items in the array
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 type incompatibility has been detected
|
1 type incompatibility has been detected
|
||||||
|
@retval
|
||||||
0 otherwise
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -286,10 +293,11 @@ void Item_func_not::print(String *str)
|
||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
special NOT for ALL subquery
|
special NOT for ALL subquery.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
longlong Item_func_not_all::val_int()
|
longlong Item_func_not_all::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
@ -322,10 +330,13 @@ void Item_func_not_all::print(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Special NOP (No OPeration) for ALL subquery it is like Item_func_not_all
|
Special NOP (No OPeration) for ALL subquery. It is like
|
||||||
(return TRUE if underlying subquery do not return rows) but if subquery
|
Item_func_not_all.
|
||||||
returns some rows it return same value as argument (TRUE/FALSE).
|
|
||||||
|
@return
|
||||||
|
(return TRUE if underlying subquery do not return rows) but if subquery
|
||||||
|
returns some rows it return same value as argument (TRUE/FALSE).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_nop_all::val_int()
|
longlong Item_func_nop_all::val_int()
|
||||||
|
|
@ -345,16 +356,9 @@ longlong Item_func_nop_all::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Convert a constant item to an int and replace the original item
|
Convert a constant item to an int and replace the original item.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
convert_constant_item()
|
|
||||||
thd thread handle
|
|
||||||
field item will be converted using the type of this field
|
|
||||||
item [in/out] reference to the item to convert
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function converts a constant expression or string to an integer.
|
The function converts a constant expression or string to an integer.
|
||||||
On successful conversion the original item is substituted for the
|
On successful conversion the original item is substituted for the
|
||||||
result of the item evaluation.
|
result of the item evaluation.
|
||||||
|
|
@ -362,16 +366,21 @@ longlong Item_func_nop_all::val_int()
|
||||||
also when comparing bigint to strings (in which case strings
|
also when comparing bigint to strings (in which case strings
|
||||||
are converted to bigints).
|
are converted to bigints).
|
||||||
|
|
||||||
NOTES
|
@param thd thread handle
|
||||||
|
@param field item will be converted using the type of this field
|
||||||
|
@param[in,out] item reference to the item to convert
|
||||||
|
|
||||||
|
@note
|
||||||
This function is called only at prepare stage.
|
This function is called only at prepare stage.
|
||||||
As all derived tables are filled only after all derived tables
|
As all derived tables are filled only after all derived tables
|
||||||
are prepared we do not evaluate items with subselects here because
|
are prepared we do not evaluate items with subselects here because
|
||||||
they can contain derived tables and thus we may attempt to use a
|
they can contain derived tables and thus we may attempt to use a
|
||||||
table that has not been populated yet.
|
table that has not been populated yet.
|
||||||
|
|
||||||
RESULT VALUES
|
@retval
|
||||||
0 Can't convert item
|
0 Can't convert item
|
||||||
1 Item was replaced with an integer version of the item
|
@retval
|
||||||
|
1 Item was replaced with an integer version of the item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool convert_constant_item(THD *thd, Field *field, Item **item)
|
static bool convert_constant_item(THD *thd, Field *field, Item **item)
|
||||||
|
|
@ -1058,13 +1067,15 @@ int Arg_comparator::compare_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare strings byte by byte. End spaces are also compared.
|
Compare strings byte by byte. End spaces are also compared.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
< 0 *a < *b
|
<0 *a < *b
|
||||||
0 *b == *b
|
@retval
|
||||||
> 0 *a > *b
|
0 *b == *b
|
||||||
|
@retval
|
||||||
|
>0 *a > *b
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Arg_comparator::compare_binary_string()
|
int Arg_comparator::compare_binary_string()
|
||||||
|
|
@ -1086,10 +1097,11 @@ int Arg_comparator::compare_binary_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare strings, but take into account that NULL == NULL
|
Compare strings, but take into account that NULL == NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int Arg_comparator::compare_e_string()
|
int Arg_comparator::compare_e_string()
|
||||||
{
|
{
|
||||||
String *res1,*res2;
|
String *res1,*res2;
|
||||||
|
|
@ -1230,7 +1242,7 @@ int Arg_comparator::compare_int_signed()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare values as BIGINT UNSIGNED.
|
Compare values as BIGINT UNSIGNED.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1253,7 +1265,7 @@ int Arg_comparator::compare_int_unsigned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare signed (*a) with unsigned (*B)
|
Compare signed (*a) with unsigned (*B)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1278,7 +1290,7 @@ int Arg_comparator::compare_int_signed_unsigned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare unsigned (*a) with signed (*B)
|
Compare unsigned (*a) with signed (*B)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1314,7 +1326,7 @@ int Arg_comparator::compare_e_int()
|
||||||
return test(val1 == val2);
|
return test(val1 == val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
Compare unsigned *a with signed *b or signed *a with unsigned *b.
|
||||||
*/
|
*/
|
||||||
int Arg_comparator::compare_e_int_diff_signedness()
|
int Arg_comparator::compare_e_int_diff_signedness()
|
||||||
|
|
@ -1603,7 +1615,7 @@ longlong Item_func_eq::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Same as Item_func_eq, but NULL = NULL */
|
/** Same as Item_func_eq, but NULL = NULL. */
|
||||||
|
|
||||||
void Item_func_equal::fix_length_and_dec()
|
void Item_func_equal::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
|
|
@ -1757,21 +1769,18 @@ void Item_func_interval::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute Item_func_interval()
|
Execute Item_func_interval().
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
Item_func_interval::val_int()
|
If we are doing a decimal comparison, we are evaluating the first
|
||||||
|
item twice.
|
||||||
|
|
||||||
NOTES
|
@return
|
||||||
If we are doing a decimal comparison, we are
|
- -1 if null value,
|
||||||
evaluating the first item twice.
|
- 0 if lower than lowest
|
||||||
|
- 1 - arg_count-1 if between args[n] and args[n+1]
|
||||||
RETURN
|
- arg_count if higher than biggest argument
|
||||||
-1 if null value,
|
|
||||||
0 if lower than lowest
|
|
||||||
1 - arg_count-1 if between args[n] and args[n+1]
|
|
||||||
arg_count if higher than biggest argument
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_interval::val_int()
|
longlong Item_func_interval::val_int()
|
||||||
|
|
@ -1853,32 +1862,31 @@ longlong Item_func_interval::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of a BETWEEN item tree
|
Perform context analysis of a BETWEEN item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_between as its root.
|
various attributes of the item tree with Item_func_between as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
|
T0(e BETWEEN e1 AND e2) = union(T1(e),T1(e1),T1(e2))
|
||||||
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T1(e BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T0(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
T1(e NOT BETWEEN e1 AND e2) = union(T1(e),intersection(T1(e1),T1(e2)))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2222,30 +2230,29 @@ Item_func_ifnull::str_op(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of an IF item tree
|
Perform context analysis of an IF item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_if as its root.
|
various attributes of the item tree with Item_func_if as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
T0(IF(e,e1,e2) = T1(IF(e,e1,e2))
|
||||||
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
T1(IF(e,e1,e2)) = intersection(T1(e1),T1(e2))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2390,11 +2397,14 @@ Item_func_nullif::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
nullif () returns NULL if arguments are equal, else it returns the
|
@note
|
||||||
first argument.
|
|
||||||
Note that we have to evaluate the first argument twice as the compare
|
Note that we have to evaluate the first argument twice as the compare
|
||||||
may have been done with a different type than return value
|
may have been done with a different type than return value
|
||||||
|
@return
|
||||||
|
NULL if arguments are equal
|
||||||
|
@return
|
||||||
|
the first argument if not equal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double
|
double
|
||||||
|
|
@ -2466,14 +2476,7 @@ Item_func_nullif::is_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return the matching ITEM or NULL if all compares (including else) failed
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
find_item()
|
|
||||||
str Buffer string
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Find and return matching items for CASE or ELSE item if all compares
|
Find and return matching items for CASE or ELSE item if all compares
|
||||||
are failed or NULL if ELSE item isn't defined.
|
are failed or NULL if ELSE item isn't defined.
|
||||||
|
|
||||||
|
|
@ -2487,9 +2490,10 @@ Item_func_nullif::is_null()
|
||||||
to it according to their int values i.e. STRING_RESULT is mapped to bit
|
to it according to their int values i.e. STRING_RESULT is mapped to bit
|
||||||
0, REAL_RESULT to bit 1, so on.
|
0, REAL_RESULT to bit 1, so on.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL - Nothing found and there is no ELSE expression defined
|
NULL Nothing found and there is no ELSE expression defined
|
||||||
item - Found item or ELSE item if defined and all comparisons are
|
@retval
|
||||||
|
item Found item or ELSE item if defined and all comparisons are
|
||||||
failed
|
failed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2738,7 +2742,10 @@ uint Item_func_case::decimal_precision() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TODO: Fix this so that it prints the whole CASE expression */
|
/**
|
||||||
|
@todo
|
||||||
|
Fix this so that it prints the whole CASE expression
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_func_case::print(String *str)
|
void Item_func_case::print(String *str)
|
||||||
{
|
{
|
||||||
|
|
@ -2780,7 +2787,7 @@ void Item_func_case::cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Coalesce - return first not NULL argument.
|
Coalesce - return first not NULL argument.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3399,32 +3406,31 @@ bool Item_func_in::nulls_in_row()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform context analysis of an IN item tree
|
Perform context analysis of an IN item tree.
|
||||||
|
|
||||||
SYNOPSIS:
|
|
||||||
fix_fields()
|
|
||||||
thd reference to the global context of the query thread
|
|
||||||
tables list of all open tables involved in the query
|
|
||||||
ref pointer to Item* variable where pointer to resulting "fixed"
|
|
||||||
item is to be assigned
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function performs context analysis (name resolution) and calculates
|
This function performs context analysis (name resolution) and calculates
|
||||||
various attributes of the item tree with Item_func_in as its root.
|
various attributes of the item tree with Item_func_in as its root.
|
||||||
The function saves in ref the pointer to the item or to a newly created
|
The function saves in ref the pointer to the item or to a newly created
|
||||||
item that is considered as a replacement for the original one.
|
item that is considered as a replacement for the original one.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the global context of the query thread
|
||||||
|
@param ref pointer to Item* variable where pointer to resulting "fixed"
|
||||||
|
item is to be assigned
|
||||||
|
|
||||||
|
@note
|
||||||
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
Let T0(e)/T1(e) be the value of not_null_tables(e) when e is used on
|
||||||
a predicate/function level. Then it's easy to show that:
|
a predicate/function level. Then it's easy to show that:
|
||||||
|
@verbatim
|
||||||
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T0(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T1(e IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
|
T0(e NOT IN(e1,...,en)) = union(T1(e),union(T1(ei)))
|
||||||
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
T1(e NOT IN(e1,...,en)) = union(T1(e),intersection(T1(ei)))
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 got error
|
1 got error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3899,25 +3905,22 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Transform an Item_cond object with a transformer callback function
|
Transform an Item_cond object with a transformer callback function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
transform()
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function recursively applies the transform method to each
|
The function recursively applies the transform method to each
|
||||||
member item of the condition list.
|
member item of the condition list.
|
||||||
If the call of the method for a member item returns a new item
|
If the call of the method for a member item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_cond object.
|
of the Item_cond object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param transformer the transformer callback function to be applied to
|
||||||
Item returned as the result of transformation of the root node
|
the nodes of the tree of the object
|
||||||
|
@param arg parameter to be passed to the transformer
|
||||||
|
|
||||||
|
@return
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||||
|
|
@ -3945,19 +3948,10 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compile Item_cond object with a processor and a transformer callback functions
|
Compile Item_cond object with a processor and a transformer
|
||||||
|
callback functions.
|
||||||
SYNOPSIS
|
|
||||||
compile()
|
|
||||||
analyzer the analyzer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_p in/out parameter to be passed to the analyzer
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_t parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
First the function applies the analyzer to the root node of
|
First the function applies the analyzer to the root node of
|
||||||
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
|
||||||
the function recursively applies the compile method to member
|
the function recursively applies the compile method to member
|
||||||
|
|
@ -3966,9 +3960,16 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_cond object.
|
of the Item_cond object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param analyzer the analyzer callback function to be applied to the
|
||||||
Item returned as the result of transformation of the root node
|
nodes of the tree of the object
|
||||||
|
@param[in,out] arg_p parameter to be passed to the analyzer
|
||||||
|
@param transformer the transformer callback function to be applied to the
|
||||||
|
nodes of the tree of the object
|
||||||
|
@param arg_t parameter to be passed to the transformer
|
||||||
|
|
||||||
|
@return
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
|
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||||
|
|
@ -4017,23 +4018,21 @@ void Item_cond::traverse_cond(Cond_traverser traverser,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Move SUM items out from item tree and replace with reference
|
Move SUM items out from item tree and replace with reference.
|
||||||
|
|
||||||
SYNOPSIS
|
The split is done to get an unique item for each SUM function
|
||||||
split_sum_func()
|
so that we can easily find and calculate them.
|
||||||
thd Thread handler
|
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||||
ref_pointer_array Pointer to array of reference fields
|
sql_select.cc)
|
||||||
fields All fields in select
|
|
||||||
|
|
||||||
NOTES
|
@param thd Thread handler
|
||||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
@param ref_pointer_array Pointer to array of reference fields
|
||||||
that have or refer (HAVING) to a SUM expression.
|
@param fields All fields in select
|
||||||
|
|
||||||
The split is done to get an unique item for each SUM function
|
@note
|
||||||
so that we can easily find and calculate them.
|
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
that have or refer (HAVING) to a SUM expression.
|
||||||
sql_select.cc)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
|
|
@ -4104,20 +4103,22 @@ void Item_cond::neg_arguments(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Evaluation of AND(expr, expr, expr ...)
|
Evaluation of AND(expr, expr, expr ...).
|
||||||
|
|
||||||
NOTES:
|
@note
|
||||||
abort_if_null is set for AND expressions for which we don't care if the
|
abort_if_null is set for AND expressions for which we don't care if the
|
||||||
result is NULL or 0. This is set for:
|
result is NULL or 0. This is set for:
|
||||||
- WHERE clause
|
- WHERE clause
|
||||||
- HAVING clause
|
- HAVING clause
|
||||||
- IF(expression)
|
- IF(expression)
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 If all expressions are true
|
1 If all expressions are true
|
||||||
|
@retval
|
||||||
0 If all expressions are false or if we find a NULL expression and
|
0 If all expressions are false or if we find a NULL expression and
|
||||||
'abort_on_null' is set.
|
'abort_on_null' is set.
|
||||||
|
@retval
|
||||||
NULL if all expression are either 1 or NULL
|
NULL if all expression are either 1 or NULL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4159,24 +4160,23 @@ longlong Item_cond_or::val_int()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create an AND expression from two expressions
|
Create an AND expression from two expressions.
|
||||||
|
|
||||||
SYNOPSIS
|
@param a expression or NULL
|
||||||
and_expressions()
|
@param b expression.
|
||||||
a expression or NULL
|
@param org_item Don't modify a if a == *org_item.
|
||||||
b expression.
|
If a == NULL, org_item is set to point at b,
|
||||||
org_item Don't modify a if a == *org_item
|
to ensure that future calls will not modify b.
|
||||||
If a == NULL, org_item is set to point at b,
|
|
||||||
to ensure that future calls will not modify b.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
This will not modify item pointed to by org_item or b
|
This will not modify item pointed to by org_item or b
|
||||||
The idea is that one can call this in a loop and create and
|
The idea is that one can call this in a loop and create and
|
||||||
'and' over all items without modifying any of the original items.
|
'and' over all items without modifying any of the original items.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL Error
|
NULL Error
|
||||||
|
@retval
|
||||||
Item
|
Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4234,7 +4234,9 @@ longlong Item_is_not_null_test::val_int()
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Optimize case of not_null_column IS NULL */
|
/**
|
||||||
|
Optimize case of not_null_column IS NULL.
|
||||||
|
*/
|
||||||
void Item_is_not_null_test::update_used_tables()
|
void Item_is_not_null_test::update_used_tables()
|
||||||
{
|
{
|
||||||
if (!args[0]->maybe_null)
|
if (!args[0]->maybe_null)
|
||||||
|
|
@ -4294,7 +4296,9 @@ longlong Item_func_like::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We can optimize a where if first character isn't a wildcard */
|
/**
|
||||||
|
We can optimize a where if first character isn't a wildcard
|
||||||
|
*/
|
||||||
|
|
||||||
Item_func::optimize_type Item_func_like::select_optimize() const
|
Item_func::optimize_type Item_func_like::select_optimize() const
|
||||||
{
|
{
|
||||||
|
|
@ -4580,10 +4584,9 @@ void Item_func_regex::cleanup()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_suffixes()
|
|
||||||
Precomputation dependent only on pattern_len.
|
Precomputation dependent only on pattern_len.
|
||||||
**********************************************************************/
|
*/
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_suffixes(int *suff)
|
void Item_func_like::turboBM_compute_suffixes(int *suff)
|
||||||
{
|
{
|
||||||
|
|
@ -4637,10 +4640,9 @@ void Item_func_like::turboBM_compute_suffixes(int *suff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_good_suffix_shifts()
|
Precomputation dependent only on pattern_len.
|
||||||
Precomputation dependent only on pattern_len.
|
*/
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
||||||
{
|
{
|
||||||
|
|
@ -4682,10 +4684,9 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_compute_bad_character_shifts()
|
Precomputation dependent on pattern_len.
|
||||||
Precomputation dependent on pattern_len.
|
*/
|
||||||
**********************************************************************/
|
|
||||||
|
|
||||||
void Item_func_like::turboBM_compute_bad_character_shifts()
|
void Item_func_like::turboBM_compute_bad_character_shifts()
|
||||||
{
|
{
|
||||||
|
|
@ -4711,10 +4712,12 @@ void Item_func_like::turboBM_compute_bad_character_shifts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**
|
||||||
turboBM_matches()
|
Search for pattern in text.
|
||||||
Search for pattern in text, returns true/false for match/no match
|
|
||||||
**********************************************************************/
|
@return
|
||||||
|
returns true/false for match/no match
|
||||||
|
*/
|
||||||
|
|
||||||
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
||||||
{
|
{
|
||||||
|
|
@ -4794,24 +4797,20 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Make a logical XOR of the arguments.
|
Make a logical XOR of the arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
val_int()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
If either operator is NULL, return NULL.
|
If either operator is NULL, return NULL.
|
||||||
|
|
||||||
NOTE
|
@todo
|
||||||
As we don't do any index optimization on XOR this is not going to be
|
(low priority) Change this to be optimized as: @n
|
||||||
very fast to use.
|
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1) @n
|
||||||
|
|
||||||
TODO (low priority)
|
|
||||||
Change this to be optimized as:
|
|
||||||
A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
|
|
||||||
To be able to do this, we would however first have to extend the MySQL
|
To be able to do this, we would however first have to extend the MySQL
|
||||||
range optimizer to handle OR better.
|
range optimizer to handle OR better.
|
||||||
|
|
||||||
|
@note
|
||||||
|
As we don't do any index optimization on XOR this is not going to be
|
||||||
|
very fast to use.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_cond_xor::val_int()
|
longlong Item_cond_xor::val_int()
|
||||||
|
|
@ -4833,15 +4832,12 @@ longlong Item_cond_xor::val_int()
|
||||||
return (longlong) result;
|
return (longlong) result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Apply NOT transformation to the item and return a new one.
|
Apply NOT transformation to the item and return a new one.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
neg_transformer()
|
|
||||||
thd thread handler
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Transform the item using next rules:
|
Transform the item using next rules:
|
||||||
|
@verbatim
|
||||||
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
a AND b AND ... -> NOT(a) OR NOT(b) OR ...
|
||||||
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
a OR b OR ... -> NOT(a) AND NOT(b) AND ...
|
||||||
NOT(a) -> a
|
NOT(a) -> a
|
||||||
|
|
@ -4853,8 +4849,11 @@ longlong Item_cond_xor::val_int()
|
||||||
a <= b -> a > b
|
a <= b -> a > b
|
||||||
IS NULL(a) -> IS NOT NULL(a)
|
IS NULL(a) -> IS NOT NULL(a)
|
||||||
IS NOT NULL(a) -> IS NULL(a)
|
IS NOT NULL(a) -> IS NULL(a)
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
RETURN
|
@param thd thread handler
|
||||||
|
|
||||||
|
@return
|
||||||
New item or
|
New item or
|
||||||
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
|
NULL if we cannot apply NOT transformation (see Item::neg_transformer()).
|
||||||
*/
|
*/
|
||||||
|
|
@ -4872,7 +4871,9 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* a IS NULL -> a IS NOT NULL */
|
/**
|
||||||
|
a IS NULL -> a IS NOT NULL.
|
||||||
|
*/
|
||||||
Item *Item_func_isnull::neg_transformer(THD *thd)
|
Item *Item_func_isnull::neg_transformer(THD *thd)
|
||||||
{
|
{
|
||||||
Item *item= new Item_func_isnotnull(args[0]);
|
Item *item= new Item_func_isnotnull(args[0]);
|
||||||
|
|
@ -4880,7 +4881,9 @@ Item *Item_func_isnull::neg_transformer(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* a IS NOT NULL -> a IS NULL */
|
/**
|
||||||
|
a IS NOT NULL -> a IS NULL.
|
||||||
|
*/
|
||||||
Item *Item_func_isnotnull::neg_transformer(THD *thd)
|
Item *Item_func_isnotnull::neg_transformer(THD *thd)
|
||||||
{
|
{
|
||||||
Item *item= new Item_func_isnull(args[0]);
|
Item *item= new Item_func_isnull(args[0]);
|
||||||
|
|
@ -4963,7 +4966,9 @@ Item *Item_func_le::negated_item() /* a <= b -> a > b */
|
||||||
return new Item_func_gt(args[0], args[1]);
|
return new Item_func_gt(args[0], args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// just fake method, should never be called
|
/**
|
||||||
|
just fake method, should never be called.
|
||||||
|
*/
|
||||||
Item *Item_bool_rowready_func2::negated_item()
|
Item *Item_bool_rowready_func2::negated_item()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
|
|
@ -5028,19 +5033,17 @@ uint Item_equal::members()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether a field is referred in the multiple equality
|
Check whether a field is referred in the multiple equality.
|
||||||
|
|
||||||
SYNOPSIS
|
The function checks whether field is occurred in the Item_equal object .
|
||||||
contains()
|
|
||||||
field field whose occurrence is to be checked
|
@param field field whose occurrence is to be checked
|
||||||
|
|
||||||
DESCRIPTION
|
@retval
|
||||||
The function checks whether field is occurred in the Item_equal object
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
1 if nultiple equality contains a reference to field
|
1 if nultiple equality contains a reference to field
|
||||||
0 otherwise
|
@retval
|
||||||
|
0 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Item_equal::contains(Field *field)
|
bool Item_equal::contains(Field *field)
|
||||||
|
|
@ -5056,22 +5059,15 @@ bool Item_equal::contains(Field *field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Join members of another Item_equal object
|
Join members of another Item_equal object.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
merge()
|
|
||||||
item multiple equality whose members are to be joined
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function actually merges two multiple equalities.
|
The function actually merges two multiple equalities.
|
||||||
After this operation the Item_equal object additionally contains
|
After this operation the Item_equal object additionally contains
|
||||||
the field items of another item of the type Item_equal.
|
the field items of another item of the type Item_equal.
|
||||||
If the optional constant items are not equal the cond_false flag is
|
If the optional constant items are not equal the cond_false flag is
|
||||||
set to 1.
|
set to 1.
|
||||||
|
@param item multiple equality whose members are to be joined
|
||||||
RETURN VALUES
|
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::merge(Item_equal *item)
|
void Item_equal::merge(Item_equal *item)
|
||||||
|
|
@ -5091,28 +5087,21 @@ void Item_equal::merge(Item_equal *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Order field items in multiple equality according to a sorting criteria
|
Order field items in multiple equality according to a sorting criteria.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
sort()
|
|
||||||
cmp function to compare field item
|
|
||||||
arg context extra parameter for the cmp function
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function perform ordering of the field items in the Item_equal
|
The function perform ordering of the field items in the Item_equal
|
||||||
object according to the criteria determined by the cmp callback parameter.
|
object according to the criteria determined by the cmp callback parameter.
|
||||||
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
|
||||||
placed after item_fiel2.
|
placed after item_fiel2.
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
The function sorts field items by the exchange sort algorithm.
|
The function sorts field items by the exchange sort algorithm.
|
||||||
The list of field items is looked through and whenever two neighboring
|
The list of field items is looked through and whenever two neighboring
|
||||||
members follow in a wrong order they are swapped. This is performed
|
members follow in a wrong order they are swapped. This is performed
|
||||||
again and again until we get all members in a right order.
|
again and again until we get all members in a right order.
|
||||||
|
|
||||||
RETURN VALUES
|
@param cmp function to compare field item
|
||||||
None
|
@param arg context extra parameter for the cmp function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
||||||
|
|
@ -5147,21 +5136,14 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check appearance of new constant items in the multiple equality object
|
Check appearance of new constant items in the multiple equality object.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
update_const()
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function checks appearance of new constant items among
|
The function checks appearance of new constant items among
|
||||||
the members of multiple equalities. Each new constant item is
|
the members of multiple equalities. Each new constant item is
|
||||||
compared with the designated constant item if there is any in the
|
compared with the designated constant item if there is any in the
|
||||||
multiple equality. If there is none the first new constant item
|
multiple equality. If there is none the first new constant item
|
||||||
becomes designated.
|
becomes designated.
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_equal::update_const()
|
void Item_equal::update_const()
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,12 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/* Functions to create an item. Used by sql_yacc.yy */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Functions to create an item. Used by sql_yac.yy
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "item_create.h"
|
#include "item_create.h"
|
||||||
|
|
|
||||||
297
sql/item_func.cc
297
sql/item_func.cc
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all numerical functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all numerical functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -46,7 +51,10 @@ bool check_reserved_words(LEX_STRING *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return TRUE if item is a constant */
|
/**
|
||||||
|
@return
|
||||||
|
TRUE if item is a constant
|
||||||
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
eval_const_cond(COND *cond)
|
eval_const_cond(COND *cond)
|
||||||
|
|
@ -237,25 +245,21 @@ void Item_func::traverse_cond(Cond_traverser traverser,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Transform an Item_func object with a transformer callback function
|
Transform an Item_func object with a transformer callback function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
transform()
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
argument parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function recursively applies the transform method to each
|
The function recursively applies the transform method to each
|
||||||
argument of the Item_func node.
|
argument of the Item_func node.
|
||||||
If the call of the method for an argument item returns a new item
|
If the call of the method for an argument item returns a new item
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_func object.
|
of the Item_func object.
|
||||||
|
@param transformer the transformer callback function to be applied to
|
||||||
RETURN VALUES
|
the nodes of the tree of the object
|
||||||
Item returned as the result of transformation of the root node
|
@param argument parameter to be passed to the transformer
|
||||||
|
|
||||||
|
@return
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||||
|
|
@ -285,19 +289,10 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compile Item_func object with a processor and a transformer callback functions
|
Compile Item_func object with a processor and a transformer
|
||||||
|
callback functions.
|
||||||
SYNOPSIS
|
|
||||||
compile()
|
|
||||||
analyzer the analyzer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_p in/out parameter to be passed to the processor
|
|
||||||
transformer the transformer callback function to be applied to the nodes
|
|
||||||
of the tree of the object
|
|
||||||
arg_t parameter to be passed to the transformer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
First the function applies the analyzer to the root node of
|
First the function applies the analyzer to the root node of
|
||||||
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
the Item_func object. Then if the analizer succeeeds (returns TRUE)
|
||||||
the function recursively applies the compile method to each argument
|
the function recursively applies the compile method to each argument
|
||||||
|
|
@ -306,9 +301,16 @@ Item *Item_func::transform(Item_transformer transformer, uchar *argument)
|
||||||
the old item is substituted for a new one.
|
the old item is substituted for a new one.
|
||||||
After this the transformer is applied to the root node
|
After this the transformer is applied to the root node
|
||||||
of the Item_func object.
|
of the Item_func object.
|
||||||
|
|
||||||
RETURN VALUES
|
@param analyzer the analyzer callback function to be applied to the
|
||||||
Item returned as the result of transformation of the root node
|
nodes of the tree of the object
|
||||||
|
@param[in,out] arg_p parameter to be passed to the processor
|
||||||
|
@param transformer the transformer callback function to be applied to the
|
||||||
|
nodes of the tree of the object
|
||||||
|
@param arg_t parameter to be passed to the transformer
|
||||||
|
|
||||||
|
@return
|
||||||
|
Item returned as the result of transformation of the root node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||||
|
|
@ -334,7 +336,9 @@ Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
|
||||||
return (this->*transformer)(arg_t);
|
return (this->*transformer)(arg_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See comments in Item_cmp_func::split_sum_func() */
|
/**
|
||||||
|
See comments in Item_cmp_func::split_sum_func()
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &fields)
|
List<Item> &fields)
|
||||||
|
|
@ -523,12 +527,9 @@ void Item_func_numhybrid::fix_num_length_and_dec()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length/decimals of function if function is fixed point and
|
Set max_length/decimals of function if function is fixed point and
|
||||||
result length/precision depends on argument ones
|
result length/precision depends on argument ones.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_decimal_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_decimal_length()
|
void Item_func::count_decimal_length()
|
||||||
|
|
@ -548,11 +549,8 @@ void Item_func::count_decimal_length()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length of if it is maximum length of its arguments
|
Set max_length of if it is maximum length of its arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_only_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_only_length()
|
void Item_func::count_only_length()
|
||||||
|
|
@ -567,12 +565,9 @@ void Item_func::count_only_length()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set max_length/decimals of function if function is floating point and
|
Set max_length/decimals of function if function is floating point and
|
||||||
result length/precision depends on argument ones
|
result length/precision depends on argument ones.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func::count_real_length()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func::count_real_length()
|
void Item_func::count_real_length()
|
||||||
|
|
@ -655,12 +650,9 @@ bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check arguments here to determine result's type for a numeric
|
Check arguments here to determine result's type for a numeric
|
||||||
function of two arguments.
|
function of two arguments.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_num_op::find_num_type()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_num_op::find_num_type(void)
|
void Item_num_op::find_num_type(void)
|
||||||
|
|
@ -699,13 +691,10 @@ void Item_num_op::find_num_type(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set result type for a numeric function of one argument
|
Set result type for a numeric function of one argument
|
||||||
(can be also used by a numeric function of many arguments, if the result
|
(can be also used by a numeric function of many arguments, if the result
|
||||||
type depends only on the first argument)
|
type depends only on the first argument)
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func_num1::find_num_type()
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_func_num1::find_num_type()
|
void Item_func_num1::find_num_type()
|
||||||
|
|
@ -1117,16 +1106,15 @@ longlong Item_func_plus::int_op()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Calculate plus of two decimail's
|
Calculate plus of two decimals.
|
||||||
|
|
||||||
SYNOPSIS
|
@param decimal_value Buffer that can be used to store result
|
||||||
decimal_op()
|
|
||||||
decimal_value Buffer that can be used to store result
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Value was NULL; In this case null_value is set
|
0 Value was NULL; In this case null_value is set
|
||||||
# Value of operation as a decimal
|
@retval
|
||||||
|
\# Value of operation as a decimal
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||||
|
|
@ -1144,11 +1132,8 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set precision of results for additive operations (+ and -)
|
Set precision of results for additive operations (+ and -)
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_func_additive_op::result_precision()
|
|
||||||
*/
|
*/
|
||||||
void Item_func_additive_op::result_precision()
|
void Item_func_additive_op::result_precision()
|
||||||
{
|
{
|
||||||
|
|
@ -1167,7 +1152,7 @@ void Item_func_additive_op::result_precision()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The following function is here to allow the user to force
|
The following function is here to allow the user to force
|
||||||
subtraction of UNSIGNED BIGINT to return negative values.
|
subtraction of UNSIGNED BIGINT to return negative values.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1199,7 +1184,9 @@ longlong Item_func_minus::int_op()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* See Item_func_plus::decimal_op for comments */
|
/**
|
||||||
|
See Item_func_plus::decimal_op for comments.
|
||||||
|
*/
|
||||||
|
|
||||||
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
|
|
@ -1238,7 +1225,7 @@ longlong Item_func_mul::int_op()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* See Item_func_plus::decimal_op for comments */
|
/** See Item_func_plus::decimal_op for comments. */
|
||||||
|
|
||||||
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
|
||||||
{
|
{
|
||||||
|
|
@ -1574,7 +1561,7 @@ void Item_func_abs::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Gateway to natural LOG function */
|
/** Gateway to natural LOG function. */
|
||||||
double Item_func_ln::val_real()
|
double Item_func_ln::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
@ -1589,10 +1576,11 @@ double Item_func_ln::val_real()
|
||||||
return log(value);
|
return log(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Extended but so slower LOG function
|
Extended but so slower LOG function.
|
||||||
We have to check if all values are > zero and first one is not one
|
|
||||||
as these are the cases then result is not a number.
|
We have to check if all values are > zero and first one is not one
|
||||||
|
as these are the cases then result is not a number.
|
||||||
*/
|
*/
|
||||||
double Item_func_log::val_real()
|
double Item_func_log::val_real()
|
||||||
{
|
{
|
||||||
|
|
@ -3021,8 +3009,10 @@ bool udf_handler::get_arguments()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This returns (String*) 0 in case of NULL values */
|
/**
|
||||||
|
@return
|
||||||
|
(String*)NULL in case of NULL values
|
||||||
|
*/
|
||||||
String *udf_handler::val_str(String *str,String *save_str)
|
String *udf_handler::val_str(String *str,String *save_str)
|
||||||
{
|
{
|
||||||
uchar is_null_tmp=0;
|
uchar is_null_tmp=0;
|
||||||
|
|
@ -3226,10 +3216,11 @@ String *Item_func_udf_str::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This has to come last in the udf_handler methods, or C for AIX
|
@note
|
||||||
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
|
This has to come last in the udf_handler methods, or C for AIX
|
||||||
*/
|
version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
|
||||||
|
*/
|
||||||
|
|
||||||
udf_handler::~udf_handler()
|
udf_handler::~udf_handler()
|
||||||
{
|
{
|
||||||
|
|
@ -3327,10 +3318,10 @@ void item_user_lock_release(User_level_lock *ull)
|
||||||
delete ull;
|
delete ull;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wait until we are at or past the given position in the master binlog
|
Wait until we are at or past the given position in the master binlog
|
||||||
on the slave
|
on the slave.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_master_pos_wait::val_int()
|
longlong Item_master_pos_wait::val_int()
|
||||||
{
|
{
|
||||||
|
|
@ -3432,11 +3423,15 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get a user level lock. If the thread has an old lock this is first released.
|
Get a user level lock. If the thread has an old lock this is first released.
|
||||||
Returns 1: Got lock
|
|
||||||
Returns 0: Timeout
|
@retval
|
||||||
Returns NULL: Error
|
1 : Got lock
|
||||||
|
@retval
|
||||||
|
0 : Timeout
|
||||||
|
@retval
|
||||||
|
NULL : Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_get_lock::val_int()
|
longlong Item_func_get_lock::val_int()
|
||||||
|
|
@ -3556,12 +3551,12 @@ longlong Item_func_get_lock::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Release a user level lock.
|
Release a user level lock.
|
||||||
Return:
|
@return
|
||||||
1 if lock released
|
- 1 if lock released
|
||||||
0 if lock wasn't held
|
- 0 if lock wasn't held
|
||||||
(SQL) NULL if no such lock
|
- (SQL) NULL if no such lock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_release_lock::val_int()
|
longlong Item_func_release_lock::val_int()
|
||||||
|
|
@ -3693,7 +3688,7 @@ void Item_func_benchmark::print(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is just used to create tests with time gaps */
|
/** This function is just used to create tests with time gaps. */
|
||||||
|
|
||||||
longlong Item_func_sleep::val_int()
|
longlong Item_func_sleep::val_int()
|
||||||
{
|
{
|
||||||
|
|
@ -3849,22 +3844,22 @@ bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set value to user variable.
|
Set value to user variable.
|
||||||
|
|
||||||
SYNOPSYS
|
@param entry pointer to structure representing variable
|
||||||
update_hash()
|
@param set_null should we set NULL value ?
|
||||||
entry - pointer to structure representing variable
|
@param ptr pointer to buffer with new value
|
||||||
set_null - should we set NULL value ?
|
@param length length of new value
|
||||||
ptr - pointer to buffer with new value
|
@param type type of new value
|
||||||
length - length of new value
|
@param cs charset info for new value
|
||||||
type - type of new value
|
@param dv derivation for new value
|
||||||
cs - charset info for new value
|
@param unsigned_arg indiates if a value of type INT_RESULT is unsigned
|
||||||
dv - derivation for new value
|
|
||||||
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success, True - failure
|
false success
|
||||||
|
@retval
|
||||||
|
true failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -3949,7 +3944,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as a double */
|
/** Get the value of a variable as a double. */
|
||||||
|
|
||||||
double user_var_entry::val_real(my_bool *null_value)
|
double user_var_entry::val_real(my_bool *null_value)
|
||||||
{
|
{
|
||||||
|
|
@ -3977,7 +3972,7 @@ double user_var_entry::val_real(my_bool *null_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as an integer */
|
/** Get the value of a variable as an integer. */
|
||||||
|
|
||||||
longlong user_var_entry::val_int(my_bool *null_value)
|
longlong user_var_entry::val_int(my_bool *null_value)
|
||||||
{
|
{
|
||||||
|
|
@ -4008,7 +4003,7 @@ longlong user_var_entry::val_int(my_bool *null_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the value of a variable as a string */
|
/** Get the value of a variable as a string. */
|
||||||
|
|
||||||
String *user_var_entry::val_str(my_bool *null_value, String *str,
|
String *user_var_entry::val_str(my_bool *null_value, String *str,
|
||||||
uint decimals)
|
uint decimals)
|
||||||
|
|
@ -4039,7 +4034,7 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
|
||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the value of a variable as a decimal */
|
/** Get the value of a variable as a decimal. */
|
||||||
|
|
||||||
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
||||||
{
|
{
|
||||||
|
|
@ -4066,18 +4061,17 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
||||||
return(val);
|
return(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This functions is invoked on SET @variable or @variable:= expression.
|
This functions is invoked on SET \@variable or
|
||||||
|
\@variable:= expression.
|
||||||
|
|
||||||
Evaluate (and check expression), store results.
|
Evaluate (and check expression), store results.
|
||||||
|
|
||||||
SYNOPSYS
|
@note
|
||||||
Item_func_set_user_var::check()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
For now it always return OK. All problem with value evaluating
|
For now it always return OK. All problem with value evaluating
|
||||||
will be caught by thd->is_error() check in sql_set_variables().
|
will be caught by thd->is_error() check in sql_set_variables().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK.
|
FALSE OK.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4126,18 +4120,17 @@ Item_func_set_user_var::check(bool use_result_field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This functions is invoked on SET @variable or @variable:= expression.
|
This functions is invoked on
|
||||||
|
SET \@variable or \@variable:= expression.
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
Item_func_set_user_var::update()
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
We have to store the expression as such in the variable, independent of
|
We have to store the expression as such in the variable, independent of
|
||||||
the value method used by the user
|
the value method used by the user
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 EOM Error
|
1 EOM Error
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
@ -4446,24 +4439,23 @@ longlong Item_func_get_user_var::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get variable by name and, if necessary, put the record of variable
|
Get variable by name and, if necessary, put the record of variable
|
||||||
use into the binary log.
|
use into the binary log.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
get_var_with_binlog()
|
|
||||||
thd Current thread
|
|
||||||
name Variable name
|
|
||||||
out_entry [out] variable structure or NULL. The pointer is set
|
|
||||||
regardless of whether function succeeded or not.
|
|
||||||
|
|
||||||
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
When a user variable is invoked from an update query (INSERT, UPDATE etc),
|
||||||
stores this variable and its value in thd->user_var_events, so that it can be
|
stores this variable and its value in thd->user_var_events, so that it can be
|
||||||
written to the binlog (will be written just before the query is written, see
|
written to the binlog (will be written just before the query is written, see
|
||||||
log.cc).
|
log.cc).
|
||||||
|
|
||||||
RETURN
|
@param thd Current thread
|
||||||
|
@param name Variable name
|
||||||
|
@param[out] out_entry variable structure or NULL. The pointer is set
|
||||||
|
regardless of whether function succeeded or not.
|
||||||
|
|
||||||
|
@retval
|
||||||
0 OK
|
0 OK
|
||||||
|
@retval
|
||||||
1 Failed to put appropriate record into binary log
|
1 Failed to put appropriate record into binary log
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
@ -5118,22 +5110,20 @@ longlong Item_func_bit_xor::val_int()
|
||||||
System variables
|
System variables
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return value of an system variable base[.name] as a constant item
|
Return value of an system variable base[.name] as a constant item.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
get_system_var()
|
@param var_type global / session
|
||||||
thd Thread handler
|
@param name Name of base or system variable
|
||||||
var_type global / session
|
@param component Component.
|
||||||
name Name of base or system variable
|
|
||||||
component Component
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If component.str = 0 then the variable name is in 'name'
|
If component.str = 0 then the variable name is in 'name'
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
0 error
|
- 0 : error
|
||||||
# constant item
|
- # : constant item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -5173,16 +5163,15 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check a user level lock.
|
Check a user level lock.
|
||||||
|
|
||||||
SYNOPSIS:
|
Sets null_value=TRUE on error.
|
||||||
val_int()
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 Available
|
1 Available
|
||||||
0 Already taken
|
@retval
|
||||||
NULL Error
|
0 Already taken, or error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_is_free_lock::val_int()
|
longlong Item_func_is_free_lock::val_int()
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all spatial functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all spatial functions
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -356,7 +361,7 @@ String *Item_func_point::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Concatenates various items into various collections
|
Concatenates various items into various collections
|
||||||
with checkings for valid wkb type of items.
|
with checkings for valid wkb type of items.
|
||||||
For example, MultiPoint can be a collection of Points only.
|
For example, MultiPoint can be a collection of Points only.
|
||||||
|
|
@ -538,6 +543,10 @@ longlong Item_func_isempty::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Ramil or Holyfoot, add real IsSimple calculation
|
||||||
|
*/
|
||||||
longlong Item_func_issimple::val_int()
|
longlong Item_func_issimple::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,18 @@
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Row items used for comparing rows and IN operations on rows:
|
Row items used for comparing rows and IN operations on rows:
|
||||||
|
|
||||||
|
@verbatim
|
||||||
(a, b, c) > (10, 10, 30)
|
(a, b, c) > (10, 10, 30)
|
||||||
(a, b, c) = (select c, d, e, from t1 where x=12)
|
(a, b, c) = (select c, d, e, from t1 where x=12)
|
||||||
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
|
(a, b, c) IN ((1,2,2), (3,4,5), (6,7,8)
|
||||||
(a, b, c) IN (select c, d, e, from t1)
|
(a, b, c) IN (select c, d, e, from t1)
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
|
@todo
|
||||||
|
think placing 2-3 component items in item (as it done for function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_row::Item_row(List<Item> &arg):
|
Item_row::Item_row(List<Item> &arg):
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,15 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all string functions
|
/**
|
||||||
** Warning: Some string functions doesn't always put and end-null on a String
|
@file
|
||||||
** (This shouldn't be needed)
|
|
||||||
|
@brief
|
||||||
|
This file defines all string functions
|
||||||
|
|
||||||
|
@warning
|
||||||
|
Some string functions don't always put and end-null on a String.
|
||||||
|
(This shouldn't be needed)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
|
@ -267,9 +273,9 @@ void Item_func_aes_decrypt::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Concatenate args with the following premises:
|
Concatenate args with the following premises:
|
||||||
If only one arg (which is ok), return value of arg
|
If only one arg (which is ok), return value of arg;
|
||||||
Don't reallocate val_str() if not absolute necessary.
|
Don't reallocate val_str() if not absolute necessary.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -425,13 +431,15 @@ void Item_func_concat::fix_length_and_dec()
|
||||||
max_length= (ulong) max_result_length;
|
max_length= (ulong) max_result_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Function des_encrypt() by tonu@spam.ee & monty
|
Function des_encrypt() by tonu@spam.ee & monty
|
||||||
Works only if compiled with OpenSSL library support.
|
Works only if compiled with OpenSSL library support.
|
||||||
This returns a binary string where first character is CHAR(128 | key-number).
|
@return
|
||||||
If one uses a string key key_number is 127.
|
A binary string where first character is CHAR(128 | key-number).
|
||||||
Encryption result is longer than original by formula:
|
If one uses a string key key_number is 127.
|
||||||
new_length= org_length + (8-(org_length % 8))+1
|
Encryption result is longer than original by formula:
|
||||||
|
@code new_length= org_length + (8-(org_length % 8))+1 @endcode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String *Item_func_des_encrypt::val_str(String *str)
|
String *Item_func_des_encrypt::val_str(String *str)
|
||||||
|
|
@ -604,7 +612,7 @@ wrong_key:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
concat with separator. First arg is the separator
|
concat with separator. First arg is the separator
|
||||||
concat_ws takes at least two arguments.
|
concat_ws takes at least two arguments.
|
||||||
*/
|
*/
|
||||||
|
|
@ -826,12 +834,14 @@ void Item_func_reverse::fix_length_and_dec()
|
||||||
max_length = args[0]->max_length;
|
max_length = args[0]->max_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Replace all occurences of string2 in string1 with string3.
|
Replace all occurences of string2 in string1 with string3.
|
||||||
** Don't reallocate val_str() if not needed
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* TODO: Fix that this works with binary strings when using USE_MB */
|
Don't reallocate val_str() if not needed.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Fix that this works with binary strings when using USE_MB
|
||||||
|
*/
|
||||||
|
|
||||||
String *Item_func_replace::val_str(String *str)
|
String *Item_func_replace::val_str(String *str)
|
||||||
{
|
{
|
||||||
|
|
@ -1796,8 +1806,9 @@ String *Item_func_database::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO: make USER() replicate properly (currently it is replicated to "")
|
@todo
|
||||||
|
make USER() replicate properly (currently it is replicated to "")
|
||||||
*/
|
*/
|
||||||
bool Item_func_user::init(const char *user, const char *host)
|
bool Item_func_user::init(const char *user, const char *host)
|
||||||
{
|
{
|
||||||
|
|
@ -1857,7 +1868,7 @@ void Item_func_soundex::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
If alpha, map input letter to soundex code.
|
If alpha, map input letter to soundex code.
|
||||||
If not alpha and remove_garbage is set then skip to next char
|
If not alpha and remove_garbage is set then skip to next char
|
||||||
else return 0
|
else return 0
|
||||||
|
|
@ -2001,9 +2012,10 @@ String *Item_func_soundex::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Change a number to format '3,333,333,333.000'
|
Change a number to format '3,333,333,333.000'.
|
||||||
** This should be 'internationalized' sometimes.
|
|
||||||
|
This should be 'internationalized' sometimes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const int FORMAT_MAX_DECIMALS= 30;
|
const int FORMAT_MAX_DECIMALS= 30;
|
||||||
|
|
@ -2022,8 +2034,9 @@ void Item_func_format::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO: This needs to be fixed for multi-byte character set where numbers
|
@todo
|
||||||
|
This needs to be fixed for multi-byte character set where numbers
|
||||||
are stored in more than one byte
|
are stored in more than one byte
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2370,9 +2383,9 @@ void Item_func_repeat::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Item_func_repeat::str is carefully written to avoid reallocs
|
Item_func_repeat::str is carefully written to avoid reallocs
|
||||||
** as much as possible at the cost of a local buffer
|
as much as possible at the cost of a local buffer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
String *Item_func_repeat::val_str(String *str)
|
String *Item_func_repeat::val_str(String *str)
|
||||||
|
|
@ -2848,7 +2861,7 @@ String *Item_func_hex::val_str(String *str)
|
||||||
return &tmp_value;
|
return &tmp_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert given hex string to a binary string */
|
/** Convert given hex string to a binary string. */
|
||||||
|
|
||||||
String *Item_func_unhex::val_str(String *str)
|
String *Item_func_unhex::val_str(String *str)
|
||||||
{
|
{
|
||||||
|
|
@ -3081,27 +3094,27 @@ String* Item_func_inet_ntoa::val_str(String* str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
||||||
|
|
||||||
|
/**
|
||||||
QUOTE() function returns argument string in single quotes suitable for
|
QUOTE() function returns argument string in single quotes suitable for
|
||||||
using in a SQL statement.
|
using in a SQL statement.
|
||||||
|
|
||||||
DESCRIPTION
|
Adds a \\ before all characters that needs to be escaped in a SQL string.
|
||||||
Adds a \ before all characters that needs to be escaped in a SQL string.
|
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
||||||
We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
|
running commands from a file in windows.
|
||||||
running commands from a file in windows.
|
|
||||||
|
|
||||||
This function is very useful when you want to generate SQL statements
|
This function is very useful when you want to generate SQL statements.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
str Quoted string
|
str Quoted string
|
||||||
NULL Out of memory.
|
@retval
|
||||||
|
NULL Out of memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
|
|
||||||
|
|
||||||
String *Item_func_quote::val_str(String *str)
|
String *Item_func_quote::val_str(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
@ -3347,8 +3360,10 @@ static uint nanoseq;
|
||||||
static ulonglong uuid_time=0;
|
static ulonglong uuid_time=0;
|
||||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||||
|
|
||||||
/* number of 100-nanosecond intervals between
|
/**
|
||||||
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
|
number of 100-nanosecond intervals between
|
||||||
|
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
|
||||||
|
*/
|
||||||
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
||||||
|
|
||||||
#define UUID_VERSION 0x1000
|
#define UUID_VERSION 0x1000
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,15 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
subselect Item
|
@file
|
||||||
|
|
||||||
SUBSELECT TODO:
|
@brief
|
||||||
- add function from mysql_select that use JOIN* as parameter to JOIN methods
|
subselect Item
|
||||||
(sql_select.h/sql_select.cc)
|
|
||||||
|
@todo
|
||||||
|
- add function from mysql_select that use JOIN* as parameter to JOIN
|
||||||
|
methods (sql_select.h/sql_select.cc)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
|
@ -403,6 +406,16 @@ void Item_singlerow_subselect::reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
- We cant change name of Item_field or Item_ref, because it will
|
||||||
|
prevent it's correct resolving, but we should save name of
|
||||||
|
removed item => we do not make optimization if top item of
|
||||||
|
list is field or reference.
|
||||||
|
- switch off this optimization for prepare statement,
|
||||||
|
because we do not rollback this changes.
|
||||||
|
Make rollback for it, or special name resolving mode in 5.0.
|
||||||
|
*/
|
||||||
Item_subselect::trans_res
|
Item_subselect::trans_res
|
||||||
Item_singlerow_subselect::select_transformer(JOIN *join)
|
Item_singlerow_subselect::select_transformer(JOIN *join)
|
||||||
{
|
{
|
||||||
|
|
@ -1445,24 +1458,24 @@ Item_in_subselect::select_transformer(JOIN *join)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
Prepare IN/ALL/ANY/SOME subquery transformation and call appropriate
|
||||||
transformation function
|
transformation function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Item_in_subselect::select_in_like_transformer()
|
|
||||||
join JOIN object of transforming subquery
|
|
||||||
func creator of condition function of subquery
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
To decide which transformation procedure (scalar or row) applicable here
|
To decide which transformation procedure (scalar or row) applicable here
|
||||||
we have to call fix_fields() for left expression to be able to call
|
we have to call fix_fields() for left expression to be able to call
|
||||||
cols() method on it. Also this method make arena management for
|
cols() method on it. Also this method make arena management for
|
||||||
underlying transformation methods.
|
underlying transformation methods.
|
||||||
|
|
||||||
RETURN
|
@param join JOIN object of transforming subquery
|
||||||
|
@param func creator of condition function of subquery
|
||||||
|
|
||||||
|
@retval
|
||||||
RES_OK OK
|
RES_OK OK
|
||||||
RES_REDUCE OK, and current subquery was reduced during transformation
|
@retval
|
||||||
|
RES_REDUCE OK, and current subquery was reduced during
|
||||||
|
transformation
|
||||||
|
@retval
|
||||||
RES_ERROR Error
|
RES_ERROR Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2423,16 +2436,15 @@ void subselect_indexsubquery_engine::print(String *str)
|
||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result object of engine
|
change select_result object of engine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2445,16 +2457,15 @@ bool subselect_single_select_engine::change_result(Item_subselect *si,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result object of engine
|
change select_result object of engine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2468,16 +2479,15 @@ bool subselect_union_engine::change_result(Item_subselect *si,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
change select_result emulation, never should be called
|
change select_result emulation, never should be called.
|
||||||
|
|
||||||
SYNOPSIS
|
@param si new subselect Item
|
||||||
subselect_single_select_engine::change_result()
|
@param res new select_result object
|
||||||
si new subselect Item
|
|
||||||
res new select_result object
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2489,14 +2499,12 @@ bool subselect_uniquesubquery_engine::change_result(Item_subselect *si,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_single_select_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
bool subselect_single_select_engine::no_tables()
|
bool subselect_single_select_engine::no_tables()
|
||||||
|
|
@ -2521,14 +2529,12 @@ bool subselect_single_select_engine::may_be_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_union_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
bool subselect_union_engine::no_tables()
|
bool subselect_union_engine::no_tables()
|
||||||
|
|
@ -2542,14 +2548,12 @@ bool subselect_union_engine::no_tables()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Report about presence of tables in subquery
|
Report about presence of tables in subquery.
|
||||||
|
|
||||||
SYNOPSIS
|
@retval
|
||||||
subselect_uniquesubquery_engine::no_tables()
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
TRUE there are not tables used in subquery
|
TRUE there are not tables used in subquery
|
||||||
|
@retval
|
||||||
FALSE there are some tables in subquery
|
FALSE there are some tables in subquery
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
153
sql/item_sum.cc
153
sql/item_sum.cc
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Sum functions (COUNT, MIN...) */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Sum functions (COUNT, MIN...)
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -23,28 +28,25 @@
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare an aggregate function item for checking context conditions
|
Prepare an aggregate function item for checking context conditions.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
init_sum_func_check()
|
|
||||||
thd reference to the thread context info
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function initializes the members of the Item_sum object created
|
The function initializes the members of the Item_sum object created
|
||||||
for a set function that are used to check validity of the set function
|
for a set function that are used to check validity of the set function
|
||||||
occurrence.
|
occurrence.
|
||||||
If the set function is not allowed in any subquery where it occurs
|
If the set function is not allowed in any subquery where it occurs
|
||||||
an error is reported immediately.
|
an error is reported immediately.
|
||||||
|
|
||||||
NOTES
|
@param thd reference to the thread context info
|
||||||
|
|
||||||
|
@note
|
||||||
This function is to be called for any item created for a set function
|
This function is to be called for any item created for a set function
|
||||||
object when the traversal of trees built for expressions used in the query
|
object when the traversal of trees built for expressions used in the query
|
||||||
is performed at the phase of context analysis. This function is to
|
is performed at the phase of context analysis. This function is to
|
||||||
be invoked at the descent of this traversal.
|
be invoked at the descent of this traversal.
|
||||||
|
@retval
|
||||||
RETURN
|
TRUE if an error is reported
|
||||||
TRUE if an error is reported
|
@retval
|
||||||
FALSE otherwise
|
FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -69,15 +71,9 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check constraints imposed on a usage of a set function
|
Check constraints imposed on a usage of a set function.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
check_sum_func()
|
|
||||||
thd reference to the thread context info
|
|
||||||
ref location of the pointer to this item in the embedding expression
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The method verifies whether context conditions imposed on a usage
|
The method verifies whether context conditions imposed on a usage
|
||||||
of any set function are met for this occurrence.
|
of any set function are met for this occurrence.
|
||||||
It checks whether the set function occurs in the position where it
|
It checks whether the set function occurs in the position where it
|
||||||
|
|
@ -89,13 +85,6 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
||||||
adds it to the chain of items for such set functions that is attached
|
adds it to the chain of items for such set functions that is attached
|
||||||
to the the st_select_lex structure for this subquery.
|
to the the st_select_lex structure for this subquery.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function is to be called for any item created for a set function
|
|
||||||
object when the traversal of trees built for expressions used in the query
|
|
||||||
is performed at the phase of context analysis. This function is to
|
|
||||||
be invoked at the ascent of this traversal.
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
A number of designated members of the object are used to check the
|
A number of designated members of the object are used to check the
|
||||||
conditions. They are specified in the comment before the Item_sum
|
conditions. They are specified in the comment before the Item_sum
|
||||||
class declaration.
|
class declaration.
|
||||||
|
|
@ -106,16 +95,28 @@ bool Item_sum::init_sum_func_check(THD *thd)
|
||||||
of set functions are allowed (i.e either in the SELECT list or
|
of set functions are allowed (i.e either in the SELECT list or
|
||||||
in the HAVING clause of the corresponding subquery)
|
in the HAVING clause of the corresponding subquery)
|
||||||
Consider the query:
|
Consider the query:
|
||||||
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
@code
|
||||||
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
|
SELECT SUM(t1.b) FROM t1 GROUP BY t1.a
|
||||||
t1.a > (SELECT MIN(t2.d) FROM t2);
|
HAVING t1.a IN (SELECT t2.c FROM t2 WHERE AVG(t1.b) > 20) AND
|
||||||
|
t1.a > (SELECT MIN(t2.d) FROM t2);
|
||||||
|
@endcode
|
||||||
allow_sum_func will contain:
|
allow_sum_func will contain:
|
||||||
for SUM(t1.b) - 1 at the first position
|
- for SUM(t1.b) - 1 at the first position
|
||||||
for AVG(t1.b) - 1 at the first position, 0 at the second position
|
- for AVG(t1.b) - 1 at the first position, 0 at the second position
|
||||||
for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
- for MIN(t2.d) - 1 at the first position, 1 at the second position.
|
||||||
|
|
||||||
RETURN
|
@param thd reference to the thread context info
|
||||||
TRUE if an error is reported
|
@param ref location of the pointer to this item in the embedding expression
|
||||||
|
|
||||||
|
@note
|
||||||
|
This function is to be called for any item created for a set function
|
||||||
|
object when the traversal of trees built for expressions used in the query
|
||||||
|
is performed at the phase of context analysis. This function is to
|
||||||
|
be invoked at the ascent of this traversal.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
TRUE if an error is reported
|
||||||
|
@retval
|
||||||
FALSE otherwise
|
FALSE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -200,15 +201,9 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Attach a set function to the subquery where it must be aggregated
|
Attach a set function to the subquery where it must be aggregated.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
register_sum_func()
|
|
||||||
thd reference to the thread context info
|
|
||||||
ref location of the pointer to this item in the embedding expression
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function looks for an outer subquery where the set function must be
|
The function looks for an outer subquery where the set function must be
|
||||||
aggregated. If it finds such a subquery then aggr_level is set to
|
aggregated. If it finds such a subquery then aggr_level is set to
|
||||||
the nest level of this subquery and the item for the set function
|
the nest level of this subquery and the item for the set function
|
||||||
|
|
@ -216,14 +211,18 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
|
||||||
inner_sum_func_list defined for each subquery. When the item is placed
|
inner_sum_func_list defined for each subquery. When the item is placed
|
||||||
there the field 'ref_by' is set to ref.
|
there the field 'ref_by' is set to ref.
|
||||||
|
|
||||||
NOTES.
|
@note
|
||||||
Now we 'register' only set functions that are aggregated in outer
|
Now we 'register' only set functions that are aggregated in outer
|
||||||
subqueries. Actually it makes sense to link all set function for
|
subqueries. Actually it makes sense to link all set function for
|
||||||
a subquery in one chain. It would simplify the process of 'splitting'
|
a subquery in one chain. It would simplify the process of 'splitting'
|
||||||
for set functions.
|
for set functions.
|
||||||
|
|
||||||
RETURN
|
@param thd reference to the thread context info
|
||||||
|
@param ref location of the pointer to this item in the embedding expression
|
||||||
|
|
||||||
|
@retval
|
||||||
FALSE if the executes without failures (currently always)
|
FALSE if the executes without failures (currently always)
|
||||||
|
@retval
|
||||||
TRUE otherwise
|
TRUE otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -311,8 +310,8 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Constructor used in processing select with temporary tebles
|
Constructor used in processing select with temporary tebles.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
Item_sum::Item_sum(THD *thd, Item_sum *item):
|
||||||
|
|
@ -655,6 +654,10 @@ Field *Item_sum_hybrid::create_tmp_field(bool group, TABLE *table,
|
||||||
** reset and add of sum_func
|
** reset and add of sum_func
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
check if the following assignments are really needed
|
||||||
|
*/
|
||||||
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
|
Item_sum_sum::Item_sum_sum(THD *thd, Item_sum_sum *item)
|
||||||
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
|
:Item_sum_num(thd, item), hybrid_type(item->hybrid_type),
|
||||||
curr_dec_buff(item->curr_dec_buff)
|
curr_dec_buff(item->curr_dec_buff)
|
||||||
|
|
@ -833,7 +836,7 @@ Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Behaves like an Integer except to fix_length_and_dec().
|
Behaves like an Integer except to fix_length_and_dec().
|
||||||
Additionally div() converts val with this traits to a val with true
|
Additionally div() converts val with this traits to a val with true
|
||||||
decimal traits along with conversion of integer value to decimal value.
|
decimal traits along with conversion of integer value to decimal value.
|
||||||
|
|
@ -910,6 +913,10 @@ void Item_sum_distinct::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
check that the case of CHAR(0) works OK
|
||||||
|
*/
|
||||||
bool Item_sum_distinct::setup(THD *thd)
|
bool Item_sum_distinct::setup(THD *thd)
|
||||||
{
|
{
|
||||||
List<Create_field> field_list;
|
List<Create_field> field_list;
|
||||||
|
|
@ -2004,8 +2011,8 @@ void Item_sum_bit::update_field()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** calc next value and merge it with field_value
|
calc next value and merge it with field_value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_sum_sum::update_field()
|
void Item_sum_sum::update_field()
|
||||||
|
|
@ -2181,6 +2188,10 @@ Item_sum_hybrid::min_max_update_int_field()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
optimize: do not get result_field in case of args[0] is NULL
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Item_sum_hybrid::min_max_update_decimal_field()
|
Item_sum_hybrid::min_max_update_decimal_field()
|
||||||
{
|
{
|
||||||
|
|
@ -2369,7 +2380,7 @@ int simple_str_key_cmp(void* arg, uchar* key1, uchar* key2)
|
||||||
return f->cmp(key1, key2);
|
return f->cmp(key1, key2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Did not make this one static - at least gcc gets confused when
|
Did not make this one static - at least gcc gets confused when
|
||||||
I try to declare a static function as a friend. If you can figure
|
I try to declare a static function as a friend. If you can figure
|
||||||
out the syntax to make a static function a friend, make this one
|
out the syntax to make a static function a friend, make this one
|
||||||
|
|
@ -2436,7 +2447,10 @@ void Item_sum_count_distinct::cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is used by rollup to create a separate usable copy of the function */
|
/**
|
||||||
|
This is used by rollup to create a separate usable copy of
|
||||||
|
the function.
|
||||||
|
*/
|
||||||
|
|
||||||
void Item_sum_count_distinct::make_unique()
|
void Item_sum_count_distinct::make_unique()
|
||||||
{
|
{
|
||||||
|
|
@ -2804,7 +2818,7 @@ my_decimal *Item_sum_udf_int::val_decimal(my_decimal *dec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Default max_length is max argument length */
|
/** Default max_length is max argument length. */
|
||||||
|
|
||||||
void Item_sum_udf_str::fix_length_and_dec()
|
void Item_sum_udf_str::fix_length_and_dec()
|
||||||
{
|
{
|
||||||
|
|
@ -2854,9 +2868,8 @@ String *Item_sum_udf_str::val_str(String *str)
|
||||||
Blobs doesn't work with DISTINCT or ORDER BY
|
Blobs doesn't work with DISTINCT or ORDER BY
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax: GROUP_CONCAT(DISTINCT expr,...)
|
||||||
GROUP_CONCAT(DISTINCT expr,...)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
||||||
|
|
@ -2893,9 +2906,8 @@ int group_concat_key_cmp_with_distinct(void* arg, uchar* key1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax: GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
||||||
|
|
@ -2937,11 +2949,11 @@ int group_concat_key_cmp_with_order(void* arg, uchar* key1, uchar* key2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
function of sort for syntax:
|
function of sort for syntax:
|
||||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... ).
|
||||||
|
|
||||||
BUG:
|
@bug
|
||||||
This doesn't work in the case when the order by contains data that
|
This doesn't work in the case when the order by contains data that
|
||||||
is not part of the field list because tree-insert will not notice
|
is not part of the field list because tree-insert will not notice
|
||||||
the duplicated values when inserting things sorted by ORDER BY
|
the duplicated values when inserting things sorted by ORDER BY
|
||||||
|
|
@ -2956,8 +2968,8 @@ int group_concat_key_cmp_with_distinct_and_order(void* arg,uchar* key1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Append data from current leaf to item->result
|
Append data from current leaf to item->result.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
||||||
|
|
@ -3028,12 +3040,13 @@ int dump_leaf_key(uchar* key, element_count count __attribute__((unused)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Constructor of Item_func_group_concat
|
Constructor of Item_func_group_concat.
|
||||||
distinct_arg - distinct
|
|
||||||
select_list - list of expression for show values
|
@param distinct_arg distinct
|
||||||
order_list - list of sort columns
|
@param select_list list of expression for show values
|
||||||
separator_arg - string value of separator
|
@param order_list list of sort columns
|
||||||
|
@param separator_arg string value of separator.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_func_group_concat::
|
Item_func_group_concat::
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,15 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* This file defines all time functions */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
This file defines all time functions
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Move month and days to language files
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
#pragma implementation // gcc: Class implementation
|
#pragma implementation // gcc: Class implementation
|
||||||
|
|
@ -24,17 +32,16 @@
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
/* TODO: Move month and days to language files */
|
/** Day number for Dec 31st, 9999. */
|
||||||
|
|
||||||
/* Day number for Dec 31st, 9999 */
|
|
||||||
#define MAX_DAY_NUMBER 3652424L
|
#define MAX_DAY_NUMBER 3652424L
|
||||||
|
|
||||||
/*
|
/**
|
||||||
OPTIMIZATION TODO:
|
@todo
|
||||||
- Replace the switch with a function that should be called for each
|
OPTIMIZATION
|
||||||
date type.
|
- Replace the switch with a function that should be called for each
|
||||||
- Remove sprintf and opencode the conversion, like we do in
|
date type.
|
||||||
Field_datetime.
|
- Remove sprintf and opencode the conversion, like we do in
|
||||||
|
Field_datetime.
|
||||||
|
|
||||||
The reason for this functions existence is that as we don't have a
|
The reason for this functions existence is that as we don't have a
|
||||||
way to know if a datetime/time value has microseconds in them
|
way to know if a datetime/time value has microseconds in them
|
||||||
|
|
@ -226,37 +233,37 @@ static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0,
|
||||||
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
|
||||||
{(char *)"%H:%i:%S", 8}};
|
{(char *)"%H:%i:%S", 8}};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Extract datetime value to MYSQL_TIME struct from string value
|
Extract datetime value to MYSQL_TIME struct from string value
|
||||||
according to format string.
|
according to format string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format date/time format specification
|
||||||
extract_date_time()
|
@param val String to decode
|
||||||
format date/time format specification
|
@param length Length of string
|
||||||
val String to decode
|
@param l_time Store result here
|
||||||
length Length of string
|
@param cached_timestamp_type It uses to get an appropriate warning
|
||||||
l_time Store result here
|
in the case when the value is truncated.
|
||||||
cached_timestamp_type
|
@param sub_pattern_end if non-zero then we are parsing string which
|
||||||
It uses to get an appropriate warning
|
should correspond compound specifier (like %T or
|
||||||
in the case when the value is truncated.
|
%r) and this parameter is pointer to place where
|
||||||
sub_pattern_end if non-zero then we are parsing string which
|
pointer to end of string matching this specifier
|
||||||
should correspond compound specifier (like %T or
|
should be stored.
|
||||||
%r) and this parameter is pointer to place where
|
|
||||||
pointer to end of string matching this specifier
|
|
||||||
should be stored.
|
|
||||||
NOTE
|
|
||||||
Possibility to parse strings matching to patterns equivalent to compound
|
|
||||||
specifiers is mainly intended for use from inside of this function in
|
|
||||||
order to understand %T and %r conversion specifiers, so number of
|
|
||||||
conversion specifiers that can be used in such sub-patterns is limited.
|
|
||||||
Also most of checks are skipped in this case.
|
|
||||||
|
|
||||||
If one adds new format specifiers to this function he should also
|
@note
|
||||||
consider adding them to get_date_time_result_type() function.
|
Possibility to parse strings matching to patterns equivalent to compound
|
||||||
|
specifiers is mainly intended for use from inside of this function in
|
||||||
|
order to understand %T and %r conversion specifiers, so number of
|
||||||
|
conversion specifiers that can be used in such sub-patterns is limited.
|
||||||
|
Also most of checks are skipped in this case.
|
||||||
|
|
||||||
RETURN
|
@note
|
||||||
0 ok
|
If one adds new format specifiers to this function he should also
|
||||||
1 error
|
consider adding them to get_date_time_result_type() function.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 ok
|
||||||
|
@retval
|
||||||
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
static bool extract_date_time(DATE_TIME_FORMAT *format,
|
||||||
|
|
@ -603,8 +610,8 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create a formated date/time value in a string
|
Create a formated date/time value in a string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||||
|
|
@ -838,7 +845,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Get a array of positive numbers from a string object.
|
Get a array of positive numbers from a string object.
|
||||||
Each number is separated by 1 non digit character
|
Each number is separated by 1 non digit character
|
||||||
Return error if there is too many numbers.
|
Return error if there is too many numbers.
|
||||||
|
|
@ -846,16 +854,14 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
|
||||||
from the high end. This allows one to give:
|
from the high end. This allows one to give:
|
||||||
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
|
||||||
|
|
||||||
SYNOPSIS
|
@param length: length of str
|
||||||
str: string value
|
@param cs: charset of str
|
||||||
length: length of str
|
@param values: array of results
|
||||||
cs: charset of str
|
@param count: count of elements in result array
|
||||||
values: array of results
|
@param transform_msec: if value is true we suppose
|
||||||
count: count of elements in result array
|
that the last part of string value is microseconds
|
||||||
transform_msec: if value is true we suppose
|
and we should transform value to six digit value.
|
||||||
that the last part of string value is microseconds
|
For example, '1.1' -> '1.100000'
|
||||||
and we should transform value to six digit value.
|
|
||||||
For example, '1.1' -> '1.100000'
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
|
||||||
|
|
@ -1046,7 +1052,9 @@ String* Item_func_monthname::val_str(String* str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns the quarter of the year
|
/**
|
||||||
|
Returns the quarter of the year.
|
||||||
|
*/
|
||||||
|
|
||||||
longlong Item_func_quarter::val_int()
|
longlong Item_func_quarter::val_int()
|
||||||
{
|
{
|
||||||
|
|
@ -1072,8 +1080,10 @@ longlong Item_func_minute::val_int()
|
||||||
(void) get_arg0_time(<ime);
|
(void) get_arg0_time(<ime);
|
||||||
return ltime.minute;
|
return ltime.minute;
|
||||||
}
|
}
|
||||||
// Returns the second in time_exp in the range of 0 - 59
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the second in time_exp in the range of 0 - 59.
|
||||||
|
*/
|
||||||
longlong Item_func_second::val_int()
|
longlong Item_func_second::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
|
|
@ -1091,7 +1101,8 @@ uint week_mode(uint mode)
|
||||||
return week_format;
|
return week_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@verbatim
|
||||||
The bits in week_format(for calc_week() function) has the following meaning:
|
The bits in week_format(for calc_week() function) has the following meaning:
|
||||||
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
|
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
|
||||||
If set Monday is first day of week
|
If set Monday is first day of week
|
||||||
|
|
@ -1118,6 +1129,7 @@ uint week_mode(uint mode)
|
||||||
four or more days in the new year, then it is week 1;
|
four or more days in the new year, then it is week 1;
|
||||||
Otherwise it is the last week of the previous year, and the
|
Otherwise it is the last week of the previous year, and the
|
||||||
next week is week 1.
|
next week is week 1.
|
||||||
|
@endverbatim
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong Item_func_week::val_int()
|
longlong Item_func_week::val_int()
|
||||||
|
|
@ -1281,8 +1293,9 @@ longlong Item_func_time_to_sec::val_int()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Convert a string to a interval value
|
Convert a string to a interval value.
|
||||||
|
|
||||||
To make code easy, allow interval objects without separators.
|
To make code easy, allow interval objects without separators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1506,7 +1519,7 @@ String *Item_func_curdate::val_str(String *str)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole CURDATE function.
|
time zone. Defines time zone (local) used for whole CURDATE function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1519,7 +1532,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
|
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1563,7 +1576,7 @@ void Item_func_curtime::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole CURTIME function.
|
time zone. Defines time zone (local) used for whole CURTIME function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1576,7 +1589,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
|
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1612,7 +1625,7 @@ void Item_func_now::fix_length_and_dec()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole NOW function.
|
time zone. Defines time zone (local) used for whole NOW function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1625,7 +1638,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
|
||||||
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
|
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1655,7 +1668,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
Converts current time in my_time_t to MYSQL_TIME represenatation for local
|
||||||
time zone. Defines time zone (local) used for whole SYSDATE function.
|
time zone. Defines time zone (local) used for whole SYSDATE function.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2618,7 +2631,7 @@ longlong Item_date_typecast::val_int()
|
||||||
return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
|
return (longlong) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MAKEDATE(a,b) is a date function that creates a date value
|
MAKEDATE(a,b) is a date function that creates a date value
|
||||||
from a year and day value.
|
from a year and day value.
|
||||||
|
|
||||||
|
|
@ -2728,7 +2741,7 @@ void Item_func_add_time::fix_length_and_dec()
|
||||||
cached_field_type= MYSQL_TYPE_TIME;
|
cached_field_type= MYSQL_TYPE_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
|
||||||
time/datetime value
|
time/datetime value
|
||||||
|
|
||||||
|
|
@ -2830,7 +2843,7 @@ void Item_func_add_time::print(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TIMEDIFF(t,s) is a time function that calculates the
|
TIMEDIFF(t,s) is a time function that calculates the
|
||||||
time value between a start and end time.
|
time value between a start and end time.
|
||||||
|
|
||||||
|
|
@ -2880,7 +2893,7 @@ null_date:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MAKETIME(h,m,s) is a time function that calculates a time value
|
MAKETIME(h,m,s) is a time function that calculates a time value
|
||||||
from the total number of hours, minutes, and seconds.
|
from the total number of hours, minutes, and seconds.
|
||||||
Result: Time value
|
Result: Time value
|
||||||
|
|
@ -2947,7 +2960,7 @@ String *Item_func_maketime::val_str(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
|
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
|
||||||
from a.
|
from a.
|
||||||
|
|
||||||
|
|
@ -3173,25 +3186,28 @@ void Item_func_get_format::print(String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get type of datetime value (DATE/TIME/...) which will be produced
|
Get type of datetime value (DATE/TIME/...) which will be produced
|
||||||
according to format string.
|
according to format string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format format string
|
||||||
get_date_time_result_type()
|
@param length length of format string
|
||||||
format - format string
|
|
||||||
length - length of format string
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
We don't process day format's characters('D', 'd', 'e') because day
|
We don't process day format's characters('D', 'd', 'e') because day
|
||||||
may be a member of all date/time types.
|
may be a member of all date/time types.
|
||||||
|
|
||||||
|
@note
|
||||||
Format specifiers supported by this function should be in sync with
|
Format specifiers supported by this function should be in sync with
|
||||||
specifiers supported by extract_date_time() function.
|
specifiers supported by extract_date_time() function.
|
||||||
|
|
||||||
RETURN VALUE
|
@return
|
||||||
One of date_time_format_types values:
|
One of date_time_format_types values:
|
||||||
DATE_TIME_MICROSECOND, DATE_TIME, DATE_ONLY, TIME_MICROSECOND, TIME_ONLY
|
- DATE_TIME_MICROSECOND
|
||||||
|
- DATE_TIME
|
||||||
|
- DATE_ONLY
|
||||||
|
- TIME_MICROSECOND
|
||||||
|
- TIME_ONLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static date_time_format_types
|
static date_time_format_types
|
||||||
|
|
|
||||||
86
sql/key.cc
86
sql/key.cc
|
|
@ -90,25 +90,19 @@ int find_ref_key(KEY *key, uint key_count, uchar *record, Field *field,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Copy part of a record that forms a key or key prefix to a buffer.
|
Copy part of a record that forms a key or key prefix to a buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
key_copy()
|
|
||||||
to_key buffer that will be used as a key
|
|
||||||
from_record full record to be copied from
|
|
||||||
key_info descriptor of the index
|
|
||||||
key_length specifies length of all keyparts that will be copied
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The function takes a complete table record (as e.g. retrieved by
|
The function takes a complete table record (as e.g. retrieved by
|
||||||
handler::index_read()), and a description of an index on the same table,
|
handler::index_read()), and a description of an index on the same table,
|
||||||
and extracts the first key_length bytes of the record which are part of a
|
and extracts the first key_length bytes of the record which are part of a
|
||||||
key into to_key. If length == 0 then copy all bytes from the record that
|
key into to_key. If length == 0 then copy all bytes from the record that
|
||||||
form a key.
|
form a key.
|
||||||
|
|
||||||
RETURN
|
@param to_key buffer that will be used as a key
|
||||||
None
|
@param from_record full record to be copied from
|
||||||
|
@param key_info descriptor of the index
|
||||||
|
@param key_length specifies length of all keyparts that will be copied
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
||||||
|
|
@ -163,22 +157,16 @@ void key_copy(uchar *to_key, uchar *from_record, KEY *key_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Restore a key from some buffer to record.
|
Restore a key from some buffer to record.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
key_restore()
|
|
||||||
to_record record buffer where the key will be restored to
|
|
||||||
from_key buffer that contains a key
|
|
||||||
key_info descriptor of the index
|
|
||||||
key_length specifies length of all keyparts that will be restored
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function converts a key into record format. It can be used in cases
|
This function converts a key into record format. It can be used in cases
|
||||||
when we want to return a key as a result row.
|
when we want to return a key as a result row.
|
||||||
|
|
||||||
RETURN
|
@param to_record record buffer where the key will be restored to
|
||||||
None
|
@param from_key buffer that contains a key
|
||||||
|
@param key_info descriptor of the index
|
||||||
|
@param key_length specifies length of all keyparts that will be restored
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
||||||
|
|
@ -255,24 +243,23 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare if a key has changed
|
Compare if a key has changed.
|
||||||
|
|
||||||
SYNOPSIS
|
@param table TABLE
|
||||||
key_cmp_if_same()
|
@param key key to compare to row
|
||||||
table TABLE
|
@param idx Index used
|
||||||
key key to compare to row
|
@param key_length Length of key
|
||||||
idx Index used
|
|
||||||
key_length Length of key
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
In theory we could just call field->cmp() for all field types,
|
In theory we could just call field->cmp() for all field types,
|
||||||
but as we are only interested if a key has changed (not if the key is
|
but as we are only interested if a key has changed (not if the key is
|
||||||
larger or smaller than the previous value) we can do things a bit
|
larger or smaller than the previous value) we can do things a bit
|
||||||
faster by using memcmp() instead.
|
faster by using memcmp() instead.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 If key is equal
|
0 If key is equal
|
||||||
|
@retval
|
||||||
1 Key has changed
|
1 Key has changed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -331,17 +318,17 @@ bool key_cmp_if_same(TABLE *table,const uchar *key,uint idx,uint key_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
unpack key-fields from record to some buffer
|
unpack key-fields from record to some buffer.
|
||||||
|
|
||||||
SYNOPSIS
|
This is used mainly to get a good error message. We temporary
|
||||||
key_unpack()
|
change the column bitmap so that all columns are readable.
|
||||||
|
|
||||||
|
@param
|
||||||
to Store value here in an easy to read form
|
to Store value here in an easy to read form
|
||||||
|
@param
|
||||||
table Table to use
|
table Table to use
|
||||||
|
@param
|
||||||
idx Key number
|
idx Key number
|
||||||
|
|
||||||
NOTES
|
|
||||||
This is used mainly to get a good error message
|
|
||||||
We temporary change the column bitmap so that all columns are readable.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void key_unpack(String *to,TABLE *table,uint idx)
|
void key_unpack(String *to,TABLE *table,uint idx)
|
||||||
|
|
@ -419,21 +406,18 @@ bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Compare key in row to a given key
|
Compare key in row to a given key.
|
||||||
|
|
||||||
SYNOPSIS
|
@param key_part Key part handler
|
||||||
key_cmp()
|
@param key Key to compare to value in table->record[0]
|
||||||
key_part Key part handler
|
@param key_length length of 'key'
|
||||||
key Key to compare to value in table->record[0]
|
|
||||||
key_length length of 'key'
|
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
The return value is SIGN(key_in_row - range_key):
|
The return value is SIGN(key_in_row - range_key):
|
||||||
|
- 0 Key is equal to range or 'range' == 0 (no range)
|
||||||
0 Key is equal to range or 'range' == 0 (no range)
|
- -1 Key is less than range
|
||||||
-1 Key is less than range
|
- 1 Key is larger than range
|
||||||
1 Key is larger than range
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
int key_cmp(KEY_PART_INFO *key_part, const uchar *key, uint key_length)
|
||||||
|
|
|
||||||
217
sql/lock.cc
217
sql/lock.cc
|
|
@ -14,8 +14,11 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* locking functions for mysql */
|
/**
|
||||||
/*
|
@file
|
||||||
|
|
||||||
|
Locking functions for mysql.
|
||||||
|
|
||||||
Because of the new concurrent inserts, we must first get external locks
|
Because of the new concurrent inserts, we must first get external locks
|
||||||
before getting internal locks. If we do it in the other order, the status
|
before getting internal locks. If we do it in the other order, the status
|
||||||
information is not up to date when called from the lock handler.
|
information is not up to date when called from the lock handler.
|
||||||
|
|
@ -65,7 +68,7 @@
|
||||||
excluding one that caused failure. That means handler must cleanup itself
|
excluding one that caused failure. That means handler must cleanup itself
|
||||||
in case external_lock() fails.
|
in case external_lock() fails.
|
||||||
|
|
||||||
TODO:
|
@todo
|
||||||
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
Change to use my_malloc() ONLY when using LOCK TABLES command or when
|
||||||
we are forced to use mysql_lock_merge.
|
we are forced to use mysql_lock_merge.
|
||||||
*/
|
*/
|
||||||
|
|
@ -390,10 +393,11 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unlock some of the tables locked by mysql_lock_tables
|
Unlock some of the tables locked by mysql_lock_tables.
|
||||||
|
|
||||||
This will work even if get_lock_data fails (next unlock will free all)
|
This will work even if get_lock_data fails (next unlock will free all)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
||||||
{
|
{
|
||||||
|
|
@ -405,8 +409,8 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** unlock all tables locked for read.
|
unlock all tables locked for read.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock)
|
||||||
|
|
@ -567,7 +571,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* abort all other threads waiting to get lock in table */
|
/** Abort all other threads waiting to get lock in table. */
|
||||||
|
|
||||||
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
||||||
{
|
{
|
||||||
|
|
@ -586,16 +590,15 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Abort one thread / table combination
|
Abort one thread / table combination.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
mysql_lock_abort_for_thread()
|
@param table Table that should be removed from lock queue
|
||||||
thd Thread handler
|
|
||||||
table Table that should be removed from lock queue
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Table was not locked by another thread
|
0 Table was not locked by another thread
|
||||||
|
@retval
|
||||||
1 Table was locked by at least one other thread
|
1 Table was locked by at least one other thread
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -663,28 +666,27 @@ MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find duplicate lock in tables.
|
Find duplicate lock in tables.
|
||||||
|
|
||||||
SYNOPSIS
|
Temporary tables are ignored here like they are ignored in
|
||||||
mysql_lock_have_duplicate()
|
get_lock_data(). If we allow two opens on temporary tables later,
|
||||||
thd The current thread.
|
both functions should be checked.
|
||||||
needle The table to check for duplicate lock.
|
|
||||||
haystack The list of tables to search for the dup lock.
|
|
||||||
|
|
||||||
NOTE
|
@param thd The current thread.
|
||||||
|
@param needle The table to check for duplicate lock.
|
||||||
|
@param haystack The list of tables to search for the dup lock.
|
||||||
|
|
||||||
|
@note
|
||||||
This is mainly meant for MERGE tables in INSERT ... SELECT
|
This is mainly meant for MERGE tables in INSERT ... SELECT
|
||||||
situations. The 'real', underlying tables can be found only after
|
situations. The 'real', underlying tables can be found only after
|
||||||
the MERGE tables are opened. This function assumes that the tables are
|
the MERGE tables are opened. This function assumes that the tables are
|
||||||
already locked.
|
already locked.
|
||||||
|
|
||||||
Temporary tables are ignored here like they are ignored in
|
@retval
|
||||||
get_lock_data(). If we allow two opens on temporary tables later,
|
NULL No duplicate lock found.
|
||||||
both functions should be checked.
|
@retval
|
||||||
|
!NULL First table from 'haystack' that matches a lock on 'needle'.
|
||||||
RETURN
|
|
||||||
NULL No duplicate lock found.
|
|
||||||
! NULL First table from 'haystack' that matches a lock on 'needle'.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||||
|
|
@ -768,7 +770,7 @@ TABLE_LIST *mysql_lock_have_duplicate(THD *thd, TABLE_LIST *needle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* unlock a set of external */
|
/** Unlock a set of external. */
|
||||||
|
|
||||||
static int unlock_external(THD *thd, TABLE **table,uint count)
|
static int unlock_external(THD *thd, TABLE **table,uint count)
|
||||||
{
|
{
|
||||||
|
|
@ -793,21 +795,17 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get lock structures from table structs and initialize locks
|
Get lock structures from table structs and initialize locks.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
get_lock_data()
|
@param table_ptr Pointer to tables that should be locks
|
||||||
thd Thread handler
|
@param flags One of:
|
||||||
table_ptr Pointer to tables that should be locks
|
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
|
||||||
flags One of:
|
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
|
||||||
GET_LOCK_UNLOCK: If we should send TL_IGNORE to
|
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
||||||
store lock
|
|
||||||
GET_LOCK_STORE_LOCKS: Store lock info in TABLE
|
|
||||||
write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||||
uint flags, TABLE **write_lock_used)
|
uint flags, TABLE **write_lock_used)
|
||||||
{
|
{
|
||||||
|
|
@ -893,31 +891,25 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Reset lock type in lock data.
|
Reset lock type in lock data.
|
||||||
|
|
||||||
SYNOPSIS
|
After a locking error we want to quit the locking of the table(s).
|
||||||
reset_lock_data()
|
The test case in the bug report for Bug #18544 has the following
|
||||||
sql_lock The MySQL lock.
|
cases:
|
||||||
|
-# Locking error in lock_external() due to InnoDB timeout.
|
||||||
|
-# Locking error in get_lock_data() due to missing write permission.
|
||||||
|
-# Locking error in wait_if_global_read_lock() due to lock conflict.
|
||||||
|
|
||||||
DESCRIPTION
|
In all these cases we have already set the lock type into the lock
|
||||||
|
data of the open table(s). If the table(s) are in the open table
|
||||||
|
cache, they could be reused with the non-zero lock type set. This
|
||||||
|
could lead to ignoring a different lock type with the next lock.
|
||||||
|
|
||||||
After a locking error we want to quit the locking of the table(s).
|
Clear the lock type of all lock data. This ensures that the next
|
||||||
The test case in the bug report for Bug #18544 has the following
|
lock request will set its lock type properly.
|
||||||
cases: 1. Locking error in lock_external() due to InnoDB timeout.
|
|
||||||
2. Locking error in get_lock_data() due to missing write permission.
|
|
||||||
3. Locking error in wait_if_global_read_lock() due to lock conflict.
|
|
||||||
|
|
||||||
In all these cases we have already set the lock type into the lock
|
@param sql_lock The MySQL lock.
|
||||||
data of the open table(s). If the table(s) are in the open table
|
|
||||||
cache, they could be reused with the non-zero lock type set. This
|
|
||||||
could lead to ignoring a different lock type with the next lock.
|
|
||||||
|
|
||||||
Clear the lock type of all lock data. This ensures that the next
|
|
||||||
lock request will set its lock type properly.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
void
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
||||||
|
|
@ -940,20 +932,19 @@ static void reset_lock_data(MYSQL_LOCK *sql_lock)
|
||||||
This is used when we need total access to a closed, not open table
|
This is used when we need total access to a closed, not open table
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Lock and wait for the named lock.
|
Lock and wait for the named lock.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
lock_and_wait_for_table_name()
|
@param table_list Lock first table in this list
|
||||||
thd Thread handler
|
|
||||||
table_list Lock first table in this list
|
|
||||||
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Works together with global read lock.
|
Works together with global read lock.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -982,30 +973,30 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Put a not open table with an old refresh version in the table cache.
|
Put a not open table with an old refresh version in the table cache.
|
||||||
|
|
||||||
SYNPOSIS
|
@param thd Thread handler
|
||||||
lock_table_name()
|
@param table_list Lock first table in this list
|
||||||
thd Thread handler
|
@param check_in_use Do we need to check if table already in use by us
|
||||||
table_list Lock first table in this list
|
|
||||||
check_in_use Do we need to check if table already in use by us
|
|
||||||
|
|
||||||
WARNING
|
@note
|
||||||
|
One must have a lock on LOCK_open!
|
||||||
|
|
||||||
|
@warning
|
||||||
If you are going to update the table, you should use
|
If you are going to update the table, you should use
|
||||||
lock_and_wait_for_table_name instead of this function as this works
|
lock_and_wait_for_table_name instead of this function as this works
|
||||||
together with 'FLUSH TABLES WITH READ LOCK'
|
together with 'FLUSH TABLES WITH READ LOCK'
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
This will force any other threads that uses the table to release it
|
This will force any other threads that uses the table to release it
|
||||||
as soon as possible.
|
as soon as possible.
|
||||||
|
|
||||||
REQUIREMENTS
|
@return
|
||||||
One must have a lock on LOCK_open !
|
|
||||||
|
|
||||||
RETURN:
|
|
||||||
< 0 error
|
< 0 error
|
||||||
|
@return
|
||||||
== 0 table locked
|
== 0 table locked
|
||||||
|
@return
|
||||||
> 0 table locked, but someone is using it
|
> 0 table locked, but someone is using it
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1102,23 +1093,22 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Lock all tables in list with a name lock
|
Lock all tables in list with a name lock.
|
||||||
|
|
||||||
SYNOPSIS
|
REQUIREMENTS
|
||||||
lock_table_names()
|
- One must have a lock on LOCK_open when calling this
|
||||||
thd Thread handle
|
|
||||||
table_list Names of tables to lock
|
|
||||||
|
|
||||||
NOTES
|
@param thd Thread handle
|
||||||
|
@param table_list Names of tables to lock
|
||||||
|
|
||||||
|
@note
|
||||||
If you are just locking one table, you should use
|
If you are just locking one table, you should use
|
||||||
lock_and_wait_for_table_name().
|
lock_and_wait_for_table_name().
|
||||||
|
|
||||||
REQUIREMENTS
|
@retval
|
||||||
One must have a lock on LOCK_open when calling this
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 Fatal error (end of memory ?)
|
1 Fatal error (end of memory ?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1148,12 +1138,13 @@ end:
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Lock all tables in list with an exclusive table name lock.
|
Unlock all tables in list with a name lock.
|
||||||
|
|
||||||
@param thd Thread handle.
|
@param thd Thread handle.
|
||||||
@param table_list Names of tables to lock.
|
@param table_list Names of tables to lock.
|
||||||
|
|
||||||
@note This function needs to be protected by LOCK_open. If we're
|
@note
|
||||||
|
This function needs to be protected by LOCK_open. If we're
|
||||||
under LOCK TABLES, this function does not work as advertised. Namely,
|
under LOCK TABLES, this function does not work as advertised. Namely,
|
||||||
it does not exclude other threads from using this table and does not
|
it does not exclude other threads from using this table and does not
|
||||||
put an exclusive name lock on this table into the table cache.
|
put an exclusive name lock on this table into the table cache.
|
||||||
|
|
@ -1183,7 +1174,7 @@ bool lock_table_names_exclusively(THD *thd, TABLE_LIST *table_list)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Test is 'table' is protected by an exclusive name lock.
|
Test is 'table' is protected by an exclusive name lock.
|
||||||
|
|
||||||
@param[in] thd The current thread handler
|
@param[in] thd The current thread handler
|
||||||
@param[in] table_list Table container containing the single table to be
|
@param[in] table_list Table container containing the single table to be
|
||||||
|
|
@ -1211,7 +1202,7 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Test is 'table key' is protected by an exclusive name lock.
|
Test is 'table key' is protected by an exclusive name lock.
|
||||||
|
|
||||||
@param[in] thd The current thread handler.
|
@param[in] thd The current thread handler.
|
||||||
@param[in] key
|
@param[in] key
|
||||||
|
|
@ -1245,23 +1236,27 @@ is_table_name_exclusively_locked_by_this_thread(THD *thd, uchar *key,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Unlock all tables in list with a name lock
|
Unlock all tables in list with a name lock.
|
||||||
|
|
||||||
SYNOPSIS
|
@param
|
||||||
unlock_table_names()
|
|
||||||
thd Thread handle
|
thd Thread handle
|
||||||
|
@param
|
||||||
table_list Names of tables to unlock
|
table_list Names of tables to unlock
|
||||||
|
@param
|
||||||
last_table Don't unlock any tables after this one.
|
last_table Don't unlock any tables after this one.
|
||||||
(default 0, which will unlock all tables)
|
(default 0, which will unlock all tables)
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
One must have a lock on LOCK_open when calling this.
|
One must have a lock on LOCK_open when calling this.
|
||||||
|
|
||||||
|
@note
|
||||||
This function will broadcast refresh signals to inform other threads
|
This function will broadcast refresh signals to inform other threads
|
||||||
that the name locks are removed.
|
that the name locks are removed.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 Fatal error (end of memory ?)
|
1 Fatal error (end of memory ?)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1565,14 +1560,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Broadcast COND_refresh and COND_global_read_lock.
|
Broadcast COND_refresh and COND_global_read_lock.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
broadcast_refresh()
|
|
||||||
void No parameters.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Due to a bug in a threading library it could happen that a signal
|
Due to a bug in a threading library it could happen that a signal
|
||||||
did not reach its target. A condition for this was that the same
|
did not reach its target. A condition for this was that the same
|
||||||
condition variable was used with different mutexes in
|
condition variable was used with different mutexes in
|
||||||
|
|
@ -1584,12 +1574,9 @@ bool make_global_read_lock_block_commit(THD *thd)
|
||||||
in global read lock handling. But now it is necessary to signal
|
in global read lock handling. But now it is necessary to signal
|
||||||
both conditions at the same time.
|
both conditions at the same time.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
When signalling COND_global_read_lock within the global read lock
|
When signalling COND_global_read_lock within the global read lock
|
||||||
handling, it is not necessary to also signal COND_refresh.
|
handling, it is not necessary to also signal COND_refresh.
|
||||||
|
|
||||||
RETURN
|
|
||||||
void
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void broadcast_refresh(void)
|
void broadcast_refresh(void)
|
||||||
|
|
|
||||||
446
sql/log.cc
446
sql/log.cc
|
|
@ -14,8 +14,15 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* logging of commands */
|
/**
|
||||||
/* TODO: Abort logging when we get an error in reading or writing log files */
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
logging of commands
|
||||||
|
|
||||||
|
@todo
|
||||||
|
Abort logging when we get an error in reading or writing log files
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sql_repl.h"
|
#include "sql_repl.h"
|
||||||
|
|
@ -689,7 +696,7 @@ void Log_to_file_event_handler::init_pthread_objects()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper around MYSQL_LOG::write() for slow log */
|
/** Wrapper around MYSQL_LOG::write() for slow log. */
|
||||||
|
|
||||||
bool Log_to_file_event_handler::
|
bool Log_to_file_event_handler::
|
||||||
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
|
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
|
||||||
|
|
@ -704,7 +711,7 @@ bool Log_to_file_event_handler::
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wrapper around MYSQL_LOG::write() for general log. We need it since we
|
Wrapper around MYSQL_LOG::write() for general log. We need it since we
|
||||||
want all log event handlers to have the same signature.
|
want all log event handlers to have the same signature.
|
||||||
*/
|
*/
|
||||||
|
|
@ -806,7 +813,7 @@ void LOGGER::cleanup_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform basic log initialization: create file-based log handler and
|
Perform basic log initialization: create file-based log handler and
|
||||||
init error log.
|
init error log.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1458,9 +1465,12 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
NOTE: how do we handle this (unlikely but legal) case:
|
@note
|
||||||
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
How do we handle this (unlikely but legal) case:
|
||||||
|
@verbatim
|
||||||
|
[transaction] + [update to non-trans table] + [rollback to savepoint] ?
|
||||||
|
@endverbatim
|
||||||
The problem occurs when a savepoint is before the update to the
|
The problem occurs when a savepoint is before the update to the
|
||||||
non-transactional table. Then when there's a rollback to the savepoint, if we
|
non-transactional table. Then when there's a rollback to the savepoint, if we
|
||||||
simply truncate the binlog cache, we lose the part of the binlog cache where
|
simply truncate the binlog cache, we lose the part of the binlog cache where
|
||||||
|
|
@ -1607,11 +1617,14 @@ static void setup_windows_event_source()
|
||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/**
|
||||||
** Find a uniq filename for 'filename.#'.
|
Find a unique filename for 'filename.#'.
|
||||||
** Set # to a number as low as possible
|
|
||||||
** returns != 0 if not possible to get uniq filename
|
Set '#' to a number as low as possible.
|
||||||
****************************************************************************/
|
|
||||||
|
@return
|
||||||
|
nonzero if not possible to get unique filename
|
||||||
|
*/
|
||||||
|
|
||||||
static int find_uniq_filename(char *name)
|
static int find_uniq_filename(char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -1825,7 +1838,7 @@ void MYSQL_LOG::close(uint exiting)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called only once */
|
/** This is called only once. */
|
||||||
|
|
||||||
void MYSQL_LOG::cleanup()
|
void MYSQL_LOG::cleanup()
|
||||||
{
|
{
|
||||||
|
|
@ -2152,6 +2165,11 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
The following should be using fn_format(); We just need to
|
||||||
|
first change fn_format() to cut the file name if it's too long.
|
||||||
|
*/
|
||||||
const char *MYSQL_LOG::generate_name(const char *log_name,
|
const char *MYSQL_LOG::generate_name(const char *log_name,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
bool strip_ext, char *buff)
|
bool strip_ext, char *buff)
|
||||||
|
|
@ -2266,17 +2284,17 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Open a (new) binlog file.
|
Open a (new) binlog file.
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
- Open the log file and the index file. Register the new
|
- Open the log file and the index file. Register the new
|
||||||
file name in it
|
file name in it
|
||||||
- When calling this when the file is in use, you must have a locks
|
- When calling this when the file is in use, you must have a locks
|
||||||
on LOCK_log and LOCK_index.
|
on LOCK_log and LOCK_index.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2428,24 +2446,20 @@ int MYSQL_BIN_LOG::raw_get_current_log(LOG_INFO* linfo)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Move all data up in a file in an filename index file
|
Move all data up in a file in an filename index file.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
copy_up_file_and_fill()
|
|
||||||
index_file File to move
|
|
||||||
offset Move everything from here to beginning
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
File will be truncated to be 'offset' shorter or filled up with
|
|
||||||
newlines
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
We do the copy outside of the IO_CACHE as the cache buffers would just
|
We do the copy outside of the IO_CACHE as the cache buffers would just
|
||||||
make things slower and more complicated.
|
make things slower and more complicated.
|
||||||
In most cases the copy loop should only do one read.
|
In most cases the copy loop should only do one read.
|
||||||
|
|
||||||
RETURN VALUES
|
@param index_file File to move
|
||||||
|
@param offset Move everything from here to beginning
|
||||||
|
|
||||||
|
@note
|
||||||
|
File will be truncated to be 'offset' shorter or filled up with newlines
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2486,25 +2500,25 @@ err:
|
||||||
|
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find the position in the log-index-file for the given log name
|
Find the position in the log-index-file for the given log name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param linfo Store here the found log file name and position to
|
||||||
find_log_pos()
|
the NEXT log file name in the index file.
|
||||||
linfo Store here the found log file name and position to
|
@param log_name Filename to find in the index file.
|
||||||
the NEXT log file name in the index file.
|
Is a null pointer if we want to read the first entry
|
||||||
log_name Filename to find in the index file.
|
@param need_lock Set this to 1 if the parent doesn't already have a
|
||||||
Is a null pointer if we want to read the first entry
|
lock on LOCK_index
|
||||||
need_lock Set this to 1 if the parent doesn't already have a
|
|
||||||
lock on LOCK_index
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
On systems without the truncate function the file will end with one or
|
On systems without the truncate function the file will end with one or
|
||||||
more empty lines. These will be ignored when reading the file.
|
more empty lines. These will be ignored when reading the file.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
LOG_INFO_EOF End of log-index-file found
|
@retval
|
||||||
|
LOG_INFO_EOF End of log-index-file found
|
||||||
|
@retval
|
||||||
LOG_INFO_IO Got IO error while reading file
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2560,25 +2574,27 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO *linfo, const char *log_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find the position in the log-index-file for the given log name
|
Find the position in the log-index-file for the given log name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param
|
||||||
find_next_log()
|
|
||||||
linfo Store here the next log file name and position to
|
linfo Store here the next log file name and position to
|
||||||
the file name after that.
|
the file name after that.
|
||||||
|
@param
|
||||||
need_lock Set this to 1 if the parent doesn't already have a
|
need_lock Set this to 1 if the parent doesn't already have a
|
||||||
lock on LOCK_index
|
lock on LOCK_index
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
- Before calling this function, one has to call find_log_pos()
|
- Before calling this function, one has to call find_log_pos()
|
||||||
to set up 'linfo'
|
to set up 'linfo'
|
||||||
- Mutex needed because we need to make sure the file pointer does not move
|
- Mutex needed because we need to make sure the file pointer does not move
|
||||||
from under our feet
|
from under our feet
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
LOG_INFO_EOF End of log-index-file found
|
@retval
|
||||||
|
LOG_INFO_EOF End of log-index-file found
|
||||||
|
@retval
|
||||||
LOG_INFO_IO Got IO error while reading file
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2612,21 +2628,20 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Delete all logs refered to in the index file
|
Delete all logs refered to in the index file.
|
||||||
Start writing to a new log file. The new index file will only contain
|
Start writing to a new log file.
|
||||||
this file.
|
|
||||||
|
|
||||||
SYNOPSIS
|
The new index file will only contain this file.
|
||||||
reset_logs()
|
|
||||||
thd Thread
|
|
||||||
|
|
||||||
NOTE
|
@param thd Thread
|
||||||
|
|
||||||
|
@note
|
||||||
If not called from slave thread, write start event to new log
|
If not called from slave thread, write start event to new log
|
||||||
|
|
||||||
|
@retval
|
||||||
RETURN VALUES
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2690,38 +2705,40 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Delete relay log files prior to rli->group_relay_log_name
|
Delete relay log files prior to rli->group_relay_log_name
|
||||||
(i.e. all logs which are not involved in a non-finished group
|
(i.e. all logs which are not involved in a non-finished group
|
||||||
(transaction)), remove them from the index file and start on next relay log.
|
(transaction)), remove them from the index file and start on next
|
||||||
|
relay log.
|
||||||
SYNOPSIS
|
|
||||||
purge_first_log()
|
|
||||||
rli Relay log information
|
|
||||||
included If false, all relay logs that are strictly before
|
|
||||||
rli->group_relay_log_name are deleted ; if true, the latter is
|
|
||||||
deleted too (i.e. all relay logs
|
|
||||||
read by the SQL slave thread are deleted).
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
- This is only called from the slave-execute thread when it has read
|
|
||||||
all commands from a relay log and want to switch to a new relay log.
|
|
||||||
- When this happens, we can be in an active transaction as
|
|
||||||
a transaction can span over two relay logs
|
|
||||||
(although it is always written as a single block to the master's binary
|
|
||||||
log, hence cannot span over two master's binary logs).
|
|
||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
- Protects index file with LOCK_index
|
- Protects index file with LOCK_index
|
||||||
- Delete relevant relay log files
|
- Delete relevant relay log files
|
||||||
- Copy all file names after these ones to the front of the index file
|
- Copy all file names after these ones to the front of the index file
|
||||||
- If the OS has truncate, truncate the file, else fill it with \n'
|
- If the OS has truncate, truncate the file, else fill it with \n'
|
||||||
- Read the next file name from the index file and store in rli->linfo
|
- Read the next file name from the index file and store in rli->linfo
|
||||||
|
|
||||||
RETURN VALUES
|
@param rli Relay log information
|
||||||
|
@param included If false, all relay logs that are strictly before
|
||||||
|
rli->group_relay_log_name are deleted ; if true, the
|
||||||
|
latter is deleted too (i.e. all relay logs
|
||||||
|
read by the SQL slave thread are deleted).
|
||||||
|
|
||||||
|
@note
|
||||||
|
- This is only called from the slave-execute thread when it has read
|
||||||
|
all commands from a relay log and want to switch to a new relay log.
|
||||||
|
- When this happens, we can be in an active transaction as
|
||||||
|
a transaction can span over two relay logs
|
||||||
|
(although it is always written as a single block to the master's binary
|
||||||
|
log, hence cannot span over two master's binary logs).
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
LOG_INFO_EOF End of log-index-file found
|
@retval
|
||||||
|
LOG_INFO_EOF End of log-index-file found
|
||||||
|
@retval
|
||||||
LOG_INFO_SEEK Could not allocate IO cache
|
LOG_INFO_SEEK Could not allocate IO cache
|
||||||
|
@retval
|
||||||
LOG_INFO_IO Got IO error while reading file
|
LOG_INFO_IO Got IO error while reading file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2799,8 +2816,8 @@ err:
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update log index_file
|
Update log index_file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
|
int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads)
|
||||||
|
|
@ -2814,25 +2831,24 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove all logs before the given log from disk and from the index file.
|
Remove all logs before the given log from disk and from the index file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param to_log Delete all log file name before this file.
|
||||||
purge_logs()
|
@param included If true, to_log is deleted too.
|
||||||
to_log Delete all log file name before this file.
|
@param need_mutex
|
||||||
included If true, to_log is deleted too.
|
@param need_update_threads If we want to update the log coordinates of
|
||||||
need_mutex
|
all threads. False for relay logs, true otherwise.
|
||||||
need_update_threads If we want to update the log coordinates of
|
@param freed_log_space If not null, decrement this variable of
|
||||||
all threads. False for relay logs, true otherwise.
|
the amount of log space freed
|
||||||
freed_log_space If not null, decrement this variable of
|
|
||||||
the amount of log space freed
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If any of the logs before the deleted one is in use,
|
If any of the logs before the deleted one is in use,
|
||||||
only purge logs up to this one.
|
only purge logs up to this one.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
LOG_INFO_EOF to_log not found
|
LOG_INFO_EOF to_log not found
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2916,21 +2932,20 @@ err:
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove all logs before the given file date from disk and from the
|
Remove all logs before the given file date from disk and from the
|
||||||
index file.
|
index file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread pointer
|
||||||
purge_logs_before_date()
|
@param before_date Delete all log files before given date.
|
||||||
thd Thread pointer
|
|
||||||
before_date Delete all log files before given date.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
If any of the logs before the deleted one is in use,
|
If any of the logs before the deleted one is in use,
|
||||||
only purge logs up to this one.
|
only purge logs up to this one.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2980,14 +2995,12 @@ err:
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create a new log file name
|
Create a new log file name.
|
||||||
|
|
||||||
SYNOPSIS
|
@param buf buf of at least FN_REFLEN where new name is stored
|
||||||
make_log_name()
|
|
||||||
buf buf of at least FN_REFLEN where new name is stored
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
If file name will be longer then FN_REFLEN it will be truncated
|
If file name will be longer then FN_REFLEN it will be truncated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3001,8 +3014,8 @@ void MYSQL_BIN_LOG::make_log_name(char* buf, const char* log_ident)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if we are writing/reading to the given log file
|
Check if we are writing/reading to the given log file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
|
bool MYSQL_BIN_LOG::is_active(const char *log_file_name_arg)
|
||||||
|
|
@ -3031,14 +3044,12 @@ void MYSQL_BIN_LOG::new_file_without_locking()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Start writing to a new log file or reopen the old file
|
Start writing to a new log file or reopen the old file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param need_lock Set to 1 if caller has not locked LOCK_log
|
||||||
new_file_impl()
|
|
||||||
need_lock Set to 1 if caller has not locked LOCK_log
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
The new file name is stored last in the index file
|
The new file name is stored last in the index file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3509,8 +3520,8 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Write an event to the binary log
|
Write an event to the binary log.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
||||||
|
|
@ -3949,27 +3960,25 @@ int MYSQL_BIN_LOG::write_cache(IO_CACHE *cache, bool lock_log, bool sync_log)
|
||||||
return 0; // All OK
|
return 0; // All OK
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Write a cached log entry to the binary log
|
Write a cached log entry to the binary log.
|
||||||
|
- To support transaction over replication, we wrap the transaction
|
||||||
|
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
||||||
|
We want to write a BEGIN/ROLLBACK block when a non-transactional table
|
||||||
|
was updated in a transaction which was rolled back. This is to ensure
|
||||||
|
that the same updates are run on the slave.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd
|
||||||
write()
|
@param cache The cache to copy to the binlog
|
||||||
thd
|
@param commit_event The commit event to print after writing the
|
||||||
cache The cache to copy to the binlog
|
|
||||||
commit_event The commit event to print after writing the
|
|
||||||
contents of the cache.
|
contents of the cache.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
- We only come here if there is something in the cache.
|
We only come here if there is something in the cache.
|
||||||
- The thing in the cache is always a complete transaction
|
@note
|
||||||
- 'cache' needs to be reinitialized after this functions returns.
|
The thing in the cache is always a complete transaction.
|
||||||
|
@note
|
||||||
IMPLEMENTATION
|
'cache' needs to be reinitialized after this functions returns.
|
||||||
- To support transaction over replication, we wrap the transaction
|
|
||||||
with BEGIN/COMMIT or BEGIN/ROLLBACK in the binary log.
|
|
||||||
We want to write a BEGIN/ROLLBACK block when a non-transactional table
|
|
||||||
was updated in a transaction which was rolled back. This is to ensure
|
|
||||||
that the same updates are run on the slave.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
|
||||||
|
|
@ -4066,17 +4075,15 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Wait until we get a signal that the binary log has been updated
|
Wait until we get a signal that the binary log has been updated.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread variable
|
||||||
wait_for_update()
|
@param is_slave If 0, the caller is the Binlog_dump thread from master;
|
||||||
thd Thread variable
|
if 1, the caller is the SQL thread from the slave. This
|
||||||
is_slave If 0, the caller is the Binlog_dump thread from master;
|
influences only thd->proc_info.
|
||||||
if 1, the caller is the SQL thread from the slave. This
|
|
||||||
influences only thd->proc_info.
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
One must have a lock on LOCK_log before calling this function.
|
One must have a lock on LOCK_log before calling this function.
|
||||||
This lock will be released before return! That's required by
|
This lock will be released before return! That's required by
|
||||||
THD::enter_cond() (see NOTES in sql_class.h).
|
THD::enter_cond() (see NOTES in sql_class.h).
|
||||||
|
|
@ -4099,18 +4106,16 @@ void MYSQL_BIN_LOG::wait_for_update(THD* thd, bool is_slave)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Close the log file
|
Close the log file.
|
||||||
|
|
||||||
SYNOPSIS
|
@param exiting Bitmask for one or more of the following bits:
|
||||||
close()
|
- LOG_CLOSE_INDEX : if we should close the index file
|
||||||
exiting Bitmask for one or more of the following bits:
|
- LOG_CLOSE_TO_BE_OPENED : if we intend to call open
|
||||||
LOG_CLOSE_INDEX if we should close the index file
|
at once after close.
|
||||||
LOG_CLOSE_TO_BE_OPENED if we intend to call open
|
- LOG_CLOSE_STOP_EVENT : write a 'stop' event to the log
|
||||||
at once after close.
|
|
||||||
LOG_CLOSE_STOP_EVENT write a 'stop' event to the log
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
One can do an open on the object at once after doing a close.
|
One can do an open on the object at once after doing a close.
|
||||||
The internal structures are not freed until cleanup() is called
|
The internal structures are not freed until cleanup() is called
|
||||||
*/
|
*/
|
||||||
|
|
@ -4190,21 +4195,20 @@ void MYSQL_BIN_LOG::set_max_size(ulong max_size_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if a string is a valid number
|
Check if a string is a valid number.
|
||||||
|
|
||||||
SYNOPSIS
|
@param str String to test
|
||||||
test_if_number()
|
@param res Store value here
|
||||||
str String to test
|
@param allow_wildcards Set to 1 if we should ignore '%' and '_'
|
||||||
res Store value here
|
|
||||||
allow_wildcards Set to 1 if we should ignore '%' and '_'
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
For the moment the allow_wildcards argument is not used
|
For the moment the allow_wildcards argument is not used
|
||||||
Should be move to some other file.
|
Should be move to some other file.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 String is a number
|
1 String is a number
|
||||||
|
@retval
|
||||||
0 Error
|
0 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4345,23 +4349,18 @@ static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
|
||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prints a printf style message to the error log and, under NT, to the
|
Prints a printf style message to the error log and, under NT, to the
|
||||||
Windows event log.
|
Windows event log.
|
||||||
|
|
||||||
SYNOPSIS
|
This function prints the message into a buffer and then sends that buffer
|
||||||
vprint_msg_to_log()
|
to other functions to write that message to other logging sources.
|
||||||
event_type Type of event to write (Error, Warning, or Info)
|
|
||||||
format Printf style format of message
|
|
||||||
args va_list list of arguments for the message
|
|
||||||
|
|
||||||
NOTE
|
@param event_type Type of event to write (Error, Warning, or Info)
|
||||||
|
@param format Printf style format of message
|
||||||
|
@param args va_list list of arguments for the message
|
||||||
|
|
||||||
IMPLEMENTATION
|
@returns
|
||||||
This function prints the message into a buffer and then sends that buffer
|
|
||||||
to other functions to write that message to other logging sources.
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
The function always returns 0. The return value is present in the
|
The function always returns 0. The return value is present in the
|
||||||
signature to be compatible with other logging routines, which could
|
signature to be compatible with other logging routines, which could
|
||||||
return an error (e.g. logging to the log tables)
|
return an error (e.g. logging to the log tables)
|
||||||
|
|
@ -4615,16 +4614,18 @@ err:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
there is no active page, let's got one from the pool
|
there is no active page, let's got one from the pool.
|
||||||
|
|
||||||
two strategies here:
|
Two strategies here:
|
||||||
1. take the first from the pool
|
-# take the first from the pool
|
||||||
2. if there're waiters - take the one with the most free space
|
-# if there're waiters - take the one with the most free space.
|
||||||
|
|
||||||
TODO page merging. try to allocate adjacent page first,
|
@todo
|
||||||
so that they can be flushed both in one sync
|
TODO page merging. try to allocate adjacent page first,
|
||||||
|
so that they can be flushed both in one sync
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TC_LOG_MMAP::get_active_from_pool()
|
void TC_LOG_MMAP::get_active_from_pool()
|
||||||
{
|
{
|
||||||
PAGE **p, **best_p=0;
|
PAGE **p, **best_p=0;
|
||||||
|
|
@ -4667,6 +4668,10 @@ void TC_LOG_MMAP::get_active_from_pool()
|
||||||
pthread_mutex_unlock(&LOCK_pool);
|
pthread_mutex_unlock(&LOCK_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
perhaps, increase log size ?
|
||||||
|
*/
|
||||||
int TC_LOG_MMAP::overflow()
|
int TC_LOG_MMAP::overflow()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -4679,10 +4684,9 @@ int TC_LOG_MMAP::overflow()
|
||||||
return 1; // always return 1
|
return 1; // always return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Record that transaction XID is committed on the persistent storage
|
Record that transaction XID is committed on the persistent storage.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function is called in the middle of two-phase commit:
|
This function is called in the middle of two-phase commit:
|
||||||
First all resources prepare the transaction, then tc_log->log() is called,
|
First all resources prepare the transaction, then tc_log->log() is called,
|
||||||
then all resources commit the transaction, then tc_log->unlog() is called.
|
then all resources commit the transaction, then tc_log->unlog() is called.
|
||||||
|
|
@ -4693,18 +4697,18 @@ int TC_LOG_MMAP::overflow()
|
||||||
threads waiting for a page, but then all these threads will be waiting
|
threads waiting for a page, but then all these threads will be waiting
|
||||||
for a fsync() anyway
|
for a fsync() anyway
|
||||||
|
|
||||||
IMPLEMENTATION
|
|
||||||
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
If tc_log == MYSQL_LOG then tc_log writes transaction to binlog and
|
||||||
records XID in a special Xid_log_event.
|
records XID in a special Xid_log_event.
|
||||||
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
If tc_log = TC_LOG_MMAP then xid is written in a special memory-mapped
|
||||||
log.
|
log.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Error
|
0 - error
|
||||||
# "cookie", a number that will be passed as an argument
|
@retval
|
||||||
to unlog() call. tc_log can define it any way it wants,
|
\# - otherwise, "cookie", a number that will be passed as an argument
|
||||||
and use for whatever purposes. TC_LOG_MMAP sets it
|
to unlog() call. tc_log can define it any way it wants,
|
||||||
to the position in memory where xid was logged to.
|
and use for whatever purposes. TC_LOG_MMAP sets it
|
||||||
|
to the position in memory where xid was logged to.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
|
int TC_LOG_MMAP::log_xid(THD *thd, my_xid xid)
|
||||||
|
|
@ -4812,9 +4816,9 @@ int TC_LOG_MMAP::sync()
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
erase xid from the page, update page free space counters/pointers.
|
erase xid from the page, update page free space counters/pointers.
|
||||||
cookie points directly to the memory where xid was logged
|
cookie points directly to the memory where xid was logged.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
|
void TC_LOG_MMAP::unlog(ulong cookie, my_xid xid)
|
||||||
|
|
@ -4925,16 +4929,17 @@ TC_LOG *tc_log;
|
||||||
TC_LOG_DUMMY tc_log_dummy;
|
TC_LOG_DUMMY tc_log_dummy;
|
||||||
TC_LOG_MMAP tc_log_mmap;
|
TC_LOG_MMAP tc_log_mmap;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Perform heuristic recovery, if --tc-heuristic-recover was used
|
Perform heuristic recovery, if --tc-heuristic-recover was used.
|
||||||
|
|
||||||
RETURN VALUE
|
@note
|
||||||
0 no heuristic recovery was requested
|
|
||||||
1 heuristic recovery was performed
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
no matter whether heuristic recovery was successful or not
|
no matter whether heuristic recovery was successful or not
|
||||||
mysqld must exit. So, return value is the same in both cases.
|
mysqld must exit. So, return value is the same in both cases.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 no heuristic recovery was requested
|
||||||
|
@retval
|
||||||
|
1 heuristic recovery was performed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int TC_LOG::using_heuristic_recover()
|
int TC_LOG::using_heuristic_recover()
|
||||||
|
|
@ -4952,8 +4957,9 @@ int TC_LOG::using_heuristic_recover()
|
||||||
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
/****** transaction coordinator log for 2pc - binlog() based solution ******/
|
||||||
#define TC_LOG_BINLOG MYSQL_BIN_LOG
|
#define TC_LOG_BINLOG MYSQL_BIN_LOG
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO keep in-memory list of prepared transactions
|
@todo
|
||||||
|
keep in-memory list of prepared transactions
|
||||||
(add to list in log(), remove on unlog())
|
(add to list in log(), remove on unlog())
|
||||||
and copy it to the new binlog if rotated
|
and copy it to the new binlog if rotated
|
||||||
but let's check the behaviour of tc_log_page_waits first!
|
but let's check the behaviour of tc_log_page_waits first!
|
||||||
|
|
@ -5044,7 +5050,7 @@ err:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this is called on shutdown, after ha_panic */
|
/** This is called on shutdown, after ha_panic. */
|
||||||
void TC_LOG_BINLOG::close()
|
void TC_LOG_BINLOG::close()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(prepared_xids==0);
|
DBUG_ASSERT(prepared_xids==0);
|
||||||
|
|
@ -5052,12 +5058,14 @@ void TC_LOG_BINLOG::close()
|
||||||
pthread_cond_destroy (&COND_prep_xids);
|
pthread_cond_destroy (&COND_prep_xids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO group commit
|
@todo
|
||||||
|
group commit
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - error
|
0 error
|
||||||
1 - success
|
@retval
|
||||||
|
1 success
|
||||||
*/
|
*/
|
||||||
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
int TC_LOG_BINLOG::log_xid(THD *thd, my_xid xid)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
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)
|
inline int ignored_error_code(int err_code)
|
||||||
|
|
@ -273,21 +273,20 @@ static char *pretty_print_str(char *packet, char *str, int len)
|
||||||
#endif /* !MYSQL_CLIENT */
|
#endif /* !MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Creates a temporary name for load data infile:
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
slave_load_file_stem()
|
Creates a temporary name for load data infile:.
|
||||||
buf Store new filename here
|
|
||||||
file_id File_id (part of file name)
|
|
||||||
event_server_id Event_id (part of file name)
|
|
||||||
ext Extension for file name
|
|
||||||
|
|
||||||
RETURN
|
@param buf Store new filename here
|
||||||
|
@param file_id File_id (part of file name)
|
||||||
|
@param event_server_id Event_id (part of file name)
|
||||||
|
@param ext Extension for file name
|
||||||
|
|
||||||
|
@return
|
||||||
Pointer to start of extension
|
Pointer to start of extension
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
static char *slave_load_file_stem(char *buf, uint file_id,
|
static char *slave_load_file_stem(char *buf, uint file_id,
|
||||||
int event_server_id, const char *ext)
|
int event_server_id, const char *ext)
|
||||||
{
|
{
|
||||||
|
|
@ -307,14 +306,12 @@ static char *slave_load_file_stem(char *buf, uint file_id,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Delete all temporary files used for SQL_LOAD.
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
cleanup_load_tmpdir()
|
Delete all temporary files used for SQL_LOAD.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
static void cleanup_load_tmpdir()
|
static void cleanup_load_tmpdir()
|
||||||
{
|
{
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
|
|
@ -382,7 +379,7 @@ static inline int read_str(const char **buf, const char *buf_end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Transforms a string into "" or its expression in 0x... form.
|
Transforms a string into "" or its expression in 0x... form.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -399,12 +396,14 @@ char *str_to_hex(char *to, const char *from, uint len)
|
||||||
return to; // pointer to end 0 of 'to'
|
return to; // pointer to end 0 of 'to'
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
|
/**
|
||||||
Append a version of the 'from' string suitable for use in a query to
|
Append a version of the 'from' string suitable for use in a query to
|
||||||
the 'to' string. To generate a correct escaping, the character set
|
the 'to' string. To generate a correct escaping, the character set
|
||||||
information in 'csinfo' is used.
|
information in 'csinfo' is used.
|
||||||
*/
|
*/
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
int
|
int
|
||||||
append_query_string(CHARSET_INFO *csinfo,
|
append_query_string(CHARSET_INFO *csinfo,
|
||||||
String const *from, String *to)
|
String const *from, String *to)
|
||||||
|
|
@ -431,7 +430,7 @@ append_query_string(CHARSET_INFO *csinfo,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
|
||||||
commands just before it prints a query.
|
commands just before it prints a query.
|
||||||
*/
|
*/
|
||||||
|
|
@ -456,8 +455,9 @@ static void print_set_option(IO_CACHE* file, uint32 bits_changed,
|
||||||
Log_event methods (= the parent class of all events)
|
Log_event methods (= the parent class of all events)
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::get_type_str()
|
@return
|
||||||
|
returns the human readable name of the event's type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char* Log_event::get_type_str()
|
const char* Log_event::get_type_str()
|
||||||
|
|
@ -505,7 +505,7 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This minimal constructor is for when you are not even sure that there
|
This minimal constructor is for when you are not even sure that there
|
||||||
is a valid THD. For example in the server when we are shutting down or
|
is a valid THD. For example in the server when we are shutting down or
|
||||||
flushing logs after receiving a SIGHUP (then we must write a Rotate to
|
flushing logs after receiving a SIGHUP (then we must write a Rotate to
|
||||||
|
|
@ -675,12 +675,9 @@ void Log_event::pack_info(Protocol *protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::net_send()
|
|
||||||
|
|
||||||
Only called by SHOW BINLOG EVENTS
|
Only called by SHOW BINLOG EVENTS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
||||||
{
|
{
|
||||||
const char *p= strrchr(log_name, FN_LIBCHAR);
|
const char *p= strrchr(log_name, FN_LIBCHAR);
|
||||||
|
|
@ -701,8 +698,10 @@ int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::init_show_field_list()
|
init_show_field_list() prepares the column names and types for the
|
||||||
|
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
|
||||||
|
EVENTS.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Log_event::init_show_field_list(List<Item>* field_list)
|
void Log_event::init_show_field_list(List<Item>* field_list)
|
||||||
|
|
@ -798,12 +797,9 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::read_log_event()
|
|
||||||
|
|
||||||
This needn't be format-tolerant, because we only read
|
This needn't be format-tolerant, because we only read
|
||||||
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
|
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||||
|
|
@ -886,14 +882,11 @@ end:
|
||||||
#define LOCK_MUTEX
|
#define LOCK_MUTEX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
#ifndef MYSQL_CLIENT
|
||||||
Log_event::read_log_event()
|
/**
|
||||||
|
@note
|
||||||
NOTE:
|
|
||||||
Allocates memory; The caller is responsible for clean-up.
|
Allocates memory; The caller is responsible for clean-up.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||||
pthread_mutex_t* log_lock,
|
pthread_mutex_t* log_lock,
|
||||||
const Format_description_log_event
|
const Format_description_log_event
|
||||||
|
|
@ -991,8 +984,7 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Log_event::read_log_event()
|
|
||||||
Binlog format tolerance is in (buf, event_len, description_event)
|
Binlog format tolerance is in (buf, event_len, description_event)
|
||||||
constructors.
|
constructors.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1329,12 +1321,13 @@ Log_event::continue_group(Relay_log_info *rli)
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::pack_info()
|
|
||||||
This (which is used only for SHOW BINLOG EVENTS) could be updated to
|
This (which is used only for SHOW BINLOG EVENTS) could be updated to
|
||||||
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
|
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
|
||||||
only an information, it does not produce suitable queries to replay (for
|
only an information, it does not produce suitable queries to replay (for
|
||||||
example it does not print LOAD DATA INFILE).
|
example it does not print LOAD DATA INFILE).
|
||||||
|
@todo
|
||||||
|
show the catalog ??
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Query_log_event::pack_info(Protocol *protocol)
|
void Query_log_event::pack_info(Protocol *protocol)
|
||||||
|
|
@ -1363,7 +1356,9 @@ void Query_log_event::pack_info(Protocol *protocol)
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/* Utility function for the next method */
|
/**
|
||||||
|
Utility function for the next method (Query_log_event::write()) .
|
||||||
|
*/
|
||||||
static void write_str_with_code_and_len(char **dst, const char *src,
|
static void write_str_with_code_and_len(char **dst, const char *src,
|
||||||
int len, uint code)
|
int len, uint code)
|
||||||
{
|
{
|
||||||
|
|
@ -1375,10 +1370,10 @@ static void write_str_with_code_and_len(char **dst, const char *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::write()
|
Query_log_event::write().
|
||||||
|
|
||||||
NOTES:
|
@note
|
||||||
In this event we have to modify the header to have the correct
|
In this event we have to modify the header to have the correct
|
||||||
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
EVENT_LEN_OFFSET as we don't yet know how many status variables we
|
||||||
will print!
|
will print!
|
||||||
|
|
@ -1555,9 +1550,7 @@ bool Query_log_event::write(IO_CACHE* file)
|
||||||
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
|
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Query_log_event::Query_log_event()
|
|
||||||
|
|
||||||
The simplest constructor that could possibly work. This is used for
|
The simplest constructor that could possibly work. This is used for
|
||||||
creating static objects that have a special meaning and are invisible
|
creating static objects that have a special meaning and are invisible
|
||||||
to the log.
|
to the log.
|
||||||
|
|
@ -1755,11 +1748,10 @@ code_name(int code)
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
|
||||||
Query_log_event::Query_log_event()
|
/**
|
||||||
This is used by the SQL slave thread to prepare the event before execution.
|
This is used by the SQL slave thread to prepare the event before execution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Query_log_event::Query_log_event(const char* buf, uint event_len,
|
Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||||
const Format_description_log_event
|
const Format_description_log_event
|
||||||
*description_event,
|
*description_event,
|
||||||
|
|
@ -1968,11 +1960,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Query_log_event::print()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
|
/**
|
||||||
|
Query_log_event::print().
|
||||||
|
|
||||||
|
@todo
|
||||||
|
print the catalog ??
|
||||||
|
*/
|
||||||
void Query_log_event::print_query_header(IO_CACHE* file,
|
void Query_log_event::print_query_header(IO_CACHE* file,
|
||||||
PRINT_EVENT_INFO* print_event_info)
|
PRINT_EVENT_INFO* print_event_info)
|
||||||
{
|
{
|
||||||
|
|
@ -2157,6 +2151,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Compare the values of "affected rows" around here. Something
|
||||||
|
like:
|
||||||
|
@code
|
||||||
|
if ((uint32) affected_in_event != (uint32) affected_on_slave)
|
||||||
|
{
|
||||||
|
sql_print_error("Slave: did not get the expected number of affected \
|
||||||
|
rows running query from master - expected %d, got %d (this numbers \
|
||||||
|
should have matched modulo 4294967296).", 0, ...);
|
||||||
|
thd->query_error = 1;
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
We may also want an option to tell the slave to ignore "affected"
|
||||||
|
mismatch. This mismatch could be implemented with a new ER_ code, and
|
||||||
|
to ignore it you would use --slave-skip-errors...
|
||||||
|
*/
|
||||||
int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
||||||
const char *query_arg, uint32 q_len_arg)
|
const char *query_arg, uint32 q_len_arg)
|
||||||
{
|
{
|
||||||
|
|
@ -2612,30 +2623,31 @@ bool Start_log_event_v3::write(IO_CACHE* file)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
Start_log_event_v3::do_apply_event()
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Start_log_event_v3::do_apply_event() .
|
||||||
The master started
|
The master started
|
||||||
|
|
||||||
IMPLEMENTATION
|
IMPLEMENTATION
|
||||||
- To handle the case where the master died without having time to write
|
- To handle the case where the master died without having time to write
|
||||||
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
|
||||||
TODO), we clean up all temporary tables that we got, if we are sure we
|
TODO), we clean up all temporary tables that we got, if we are sure we
|
||||||
can (see below).
|
can (see below).
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
- Remove all active user locks.
|
- Remove all active user locks.
|
||||||
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
|
||||||
the use of a bit of memory for a user lock which will not be used
|
the use of a bit of memory for a user lock which will not be used
|
||||||
anymore. If the user lock is later used, the old one will be released. In
|
anymore. If the user lock is later used, the old one will be released. In
|
||||||
other words, no deadlock problem.
|
other words, no deadlock problem.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
DBUG_ENTER("Start_log_event_v3::do_apply_event");
|
||||||
switch (binlog_version) {
|
switch (binlog_version)
|
||||||
|
{
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
/*
|
/*
|
||||||
|
|
@ -2683,23 +2695,20 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
|
||||||
Format_description_log_event methods
|
Format_description_log_event methods
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Format_description_log_event 1st ctor.
|
Format_description_log_event 1st ctor.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
Format_description_log_event::Format_description_log_event
|
|
||||||
binlog_version the binlog version for which we want to build
|
|
||||||
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
|
|
||||||
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
|
|
||||||
old 4.0 (binlog version 2) is not supported;
|
|
||||||
it should not be used for replication with
|
|
||||||
5.0.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Ctor. Can be used to create the event to write to the binary log (when the
|
Ctor. Can be used to create the event to write to the binary log (when the
|
||||||
server starts or when FLUSH LOGS), or to create artificial events to parse
|
server starts or when FLUSH LOGS), or to create artificial events to parse
|
||||||
binlogs from MySQL 3.23 or 4.x.
|
binlogs from MySQL 3.23 or 4.x.
|
||||||
When in a client, only the 2nd use is possible.
|
When in a client, only the 2nd use is possible.
|
||||||
|
|
||||||
|
@param binlog_version the binlog version for which we want to build
|
||||||
|
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
|
||||||
|
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
|
||||||
|
old 4.0 (binlog version 2) is not supported;
|
||||||
|
it should not be used for replication with
|
||||||
|
5.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Format_description_log_event::
|
Format_description_log_event::
|
||||||
|
|
@ -2807,18 +2816,20 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The problem with this constructor is that the fixed header may have a
|
The problem with this constructor is that the fixed header may have a
|
||||||
length different from this version, but we don't know this length as we
|
length different from this version, but we don't know this length as we
|
||||||
have not read the Format_description_log_event which says it, yet. This
|
have not read the Format_description_log_event which says it, yet. This
|
||||||
length is in the post-header of the event, but we don't know where the
|
length is in the post-header of the event, but we don't know where the
|
||||||
post-header starts.
|
post-header starts.
|
||||||
|
|
||||||
So this type of event HAS to:
|
So this type of event HAS to:
|
||||||
- either have the header's length at the beginning (in the header, at a
|
- either have the header's length at the beginning (in the header, at a
|
||||||
fixed position which will never be changed), not in the post-header. That
|
fixed position which will never be changed), not in the post-header. That
|
||||||
would make the header be "shifted" compared to other events.
|
would make the header be "shifted" compared to other events.
|
||||||
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
|
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
|
||||||
versions, so that we know for sure.
|
versions, so that we know for sure.
|
||||||
|
|
||||||
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
|
||||||
it is sent before Format_description_log_event).
|
it is sent before Format_description_log_event).
|
||||||
*/
|
*/
|
||||||
|
|
@ -3253,14 +3264,11 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
||||||
#endif /* !MYSQL_CLIENT */
|
#endif /* !MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Load_log_event::Load_log_event()
|
@note
|
||||||
|
|
||||||
NOTE
|
|
||||||
The caller must do buf[event_len] = 0 before he starts using the
|
The caller must do buf[event_len] = 0 before he starts using the
|
||||||
constructed event.
|
constructed event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
Load_log_event::Load_log_event(const char *buf, uint event_len,
|
||||||
const Format_description_log_event *description_event)
|
const Format_description_log_event *description_event)
|
||||||
:Log_event(buf, description_event), num_fields(0), fields(0),
|
:Log_event(buf, description_event), num_fields(0), fields(0),
|
||||||
|
|
@ -3435,17 +3443,18 @@ void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
|
||||||
}
|
}
|
||||||
#endif /* MYSQL_CLIENT */
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Load_log_event::set_fields()
|
Load_log_event::set_fields()
|
||||||
|
|
||||||
Note that this function can not use the member variable
|
@note
|
||||||
for the database, since LOAD DATA INFILE on the slave
|
This function can not use the member variable
|
||||||
can be for a different database than the current one.
|
for the database, since LOAD DATA INFILE on the slave
|
||||||
This is the reason for the affected_db argument to this method.
|
can be for a different database than the current one.
|
||||||
|
This is the reason for the affected_db argument to this method.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
void Load_log_event::set_fields(const char* affected_db,
|
void Load_log_event::set_fields(const char* affected_db,
|
||||||
List<Item> &field_list,
|
List<Item> &field_list,
|
||||||
Name_resolution_context *context)
|
Name_resolution_context *context)
|
||||||
|
|
@ -3463,32 +3472,33 @@ void Load_log_event::set_fields(const char* affected_db,
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
/*
|
/**
|
||||||
Does the data loading job when executing a LOAD DATA on the slave
|
Does the data loading job when executing a LOAD DATA on the slave.
|
||||||
|
|
||||||
SYNOPSIS
|
@param net
|
||||||
Load_log_event::do_apply_event
|
@param rli
|
||||||
net
|
@param use_rli_only_for_errors If set to 1, rli is provided to
|
||||||
rli
|
Load_log_event::exec_event only for this
|
||||||
use_rli_only_for_errors - if set to 1, rli is provided to
|
function to have RPL_LOG_NAME and
|
||||||
Load_log_event::do_apply_event
|
rli->last_slave_error, both being used by
|
||||||
only for this function to have
|
error reports. rli's position advancing
|
||||||
RPL_LOG_NAME and
|
is skipped (done by the caller which is
|
||||||
rli->last_slave_error, both being
|
Execute_load_log_event::exec_event).
|
||||||
used by error reports. rli's
|
If set to 0, rli is provided for full use,
|
||||||
position advancing is skipped (done
|
i.e. for error reports and position
|
||||||
by the caller which is
|
advancing.
|
||||||
Execute_load_log_event::do_apply_event).
|
|
||||||
- if set to 0, rli is provided for
|
|
||||||
full use, i.e. for error reports and
|
|
||||||
position advancing.
|
|
||||||
|
|
||||||
DESCRIPTION
|
@todo
|
||||||
Does the data loading job when executing a LOAD DATA on the slave
|
fix this; this can be done by testing rules in
|
||||||
|
Create_file_log_event::exec_event() and then discarding Append_block and
|
||||||
|
al.
|
||||||
|
@todo
|
||||||
|
this is a bug - this needs to be moved to the I/O thread
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 Success
|
0 Success
|
||||||
1 Failure
|
@retval
|
||||||
|
1 Failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
||||||
|
|
@ -3864,24 +3874,21 @@ bool Rotate_log_event::write(IO_CACHE* file)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Rotate_log_event::do_apply_event()
|
Got a rotate log event from the master.
|
||||||
|
|
||||||
Got a rotate log event from the master
|
This is mainly used so that we can later figure out the logname and
|
||||||
|
position for the master.
|
||||||
|
|
||||||
IMPLEMENTATION
|
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
||||||
This is mainly used so that we can later figure out the logname and
|
in a A -> B -> A setup.
|
||||||
position for the master.
|
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
||||||
|
|
||||||
We can't rotate the slave's BINlog as this will cause infinitive rotations
|
@retval
|
||||||
in a A -> B -> A setup.
|
|
||||||
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
|
|
||||||
|
|
||||||
RETURN VALUES
|
|
||||||
0 ok
|
0 ok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
|
||||||
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
DBUG_ENTER("Rotate_log_event::do_update_pos");
|
||||||
|
|
@ -4233,12 +4240,12 @@ void Xid_log_event::pack_info(Protocol *protocol)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
NOTE it's ok not to use int8store here,
|
@note
|
||||||
|
It's ok not to use int8store here,
|
||||||
as long as xid_t::set(ulonglong) and
|
as long as xid_t::set(ulonglong) and
|
||||||
xid_t::get_my_xid doesn't do it either
|
xid_t::get_my_xid doesn't do it either.
|
||||||
|
We don't care about actual values of xids as long as
|
||||||
we don't care about actual values of xids as long as
|
|
||||||
identical numbers compare identically
|
identical numbers compare identically
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4717,6 +4724,10 @@ void Slave_log_event::pack_info(Protocol *protocol)
|
||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
re-write this better without holding both locks at the same time
|
||||||
|
*/
|
||||||
Slave_log_event::Slave_log_event(THD* thd_arg,
|
Slave_log_event::Slave_log_event(THD* thd_arg,
|
||||||
Relay_log_info* rli)
|
Relay_log_info* rli)
|
||||||
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
|
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
|
||||||
|
|
@ -4812,7 +4823,7 @@ void Slave_log_event::init_from_mem_pool(int data_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This code is not used, so has not been updated to be format-tolerant */
|
/** This code is not used, so has not been updated to be format-tolerant. */
|
||||||
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
|
||||||
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
|
||||||
{
|
{
|
||||||
|
|
@ -4860,9 +4871,8 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
||||||
#endif /* MYSQL_CLIENT */
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
/*
|
/*
|
||||||
Stop_log_event::do_apply_event()
|
|
||||||
|
|
||||||
The master stopped. We used to clean up all temporary tables but
|
The master stopped. We used to clean up all temporary tables but
|
||||||
this is useless as, as the master has shut down properly, it has
|
this is useless as, as the master has shut down properly, it has
|
||||||
written all DROP TEMPORARY TABLE (prepared statements' deletion is
|
written all DROP TEMPORARY TABLE (prepared statements' deletion is
|
||||||
|
|
@ -4873,8 +4883,6 @@ void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
||||||
Start_log_event_v3::do_apply_event(), not here. Because if we come
|
Start_log_event_v3::do_apply_event(), not here. Because if we come
|
||||||
here, the master was sane.
|
here, the master was sane.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
int Stop_log_event::do_update_pos(Relay_log_info *rli)
|
int Stop_log_event::do_update_pos(Relay_log_info *rli)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
@ -5698,7 +5706,9 @@ void Execute_load_query_log_event::print(FILE* file,
|
||||||
print(file, print_event_info, 0);
|
print(file, print_event_info, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Prints the query as LOAD DATA LOCAL and with rewritten filename.
|
||||||
|
*/
|
||||||
void Execute_load_query_log_event::print(FILE* file,
|
void Execute_load_query_log_event::print(FILE* file,
|
||||||
PRINT_EVENT_INFO* print_event_info,
|
PRINT_EVENT_INFO* print_event_info,
|
||||||
const char *local_fname)
|
const char *local_fname)
|
||||||
|
|
@ -6755,15 +6765,17 @@ void Rows_log_event::print_helper(FILE *file,
|
||||||
type used is uint32.
|
type used is uint32.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if !defined(MYSQL_CLIENT)
|
||||||
/**
|
/**
|
||||||
Save the field metadata based on the real_type of the field.
|
Save the field metadata based on the real_type of the field.
|
||||||
The metadata saved depends on the type of the field. Some fields
|
The metadata saved depends on the type of the field. Some fields
|
||||||
store a single byte for pack_length() while others store two bytes
|
store a single byte for pack_length() while others store two bytes
|
||||||
for field_length (max length).
|
for field_length (max length).
|
||||||
|
|
||||||
@retval 0 Ok.
|
@retval 0 Ok.
|
||||||
|
|
||||||
TODO: We may want to consider changing the encoding of the information.
|
@todo
|
||||||
|
We may want to consider changing the encoding of the information.
|
||||||
Currently, the code attempts to minimize the number of bytes written to
|
Currently, the code attempts to minimize the number of bytes written to
|
||||||
the tablemap. There are at least two other alternatives; 1) using
|
the tablemap. There are at least two other alternatives; 1) using
|
||||||
net_store_length() to store the data allowing it to choose the number of
|
net_store_length() to store the data allowing it to choose the number of
|
||||||
|
|
@ -6778,7 +6790,6 @@ void Rows_log_event::print_helper(FILE *file,
|
||||||
is less wasteful for space but does waste 1 byte for every field that does
|
is less wasteful for space but does waste 1 byte for every field that does
|
||||||
not encode 2 parts.
|
not encode 2 parts.
|
||||||
*/
|
*/
|
||||||
#if !defined(MYSQL_CLIENT)
|
|
||||||
int Table_map_log_event::save_field_metadata()
|
int Table_map_log_event::save_field_metadata()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
DBUG_ENTER("Table_map_log_event::save_field_metadata");
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,11 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Cashing of files with only does (sequential) read or writes of fixed-
|
@file
|
||||||
|
|
||||||
|
@details
|
||||||
|
Caching of files with only does (sequential) read or writes of fixed-
|
||||||
length records. A read isn't allowed to go over file-length. A read is ok
|
length records. A read isn't allowed to go over file-length. A read is ok
|
||||||
if it ends at file-length and next read can try to read after file-length
|
if it ends at file-length and next read can try to read after file-length
|
||||||
(and get a EOF-error).
|
(and get a EOF-error).
|
||||||
|
|
@ -34,11 +37,15 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
/*
|
/**
|
||||||
** Read buffered from the net.
|
Read buffered from the net.
|
||||||
** Returns 1 if can't read requested characters
|
|
||||||
** Returns 0 if record read
|
@retval
|
||||||
*/
|
1 if can't read requested characters
|
||||||
|
@retval
|
||||||
|
0 if record read
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
int _my_b_net_read(register IO_CACHE *info, uchar *Buffer,
|
||||||
size_t Count __attribute__((unused)))
|
size_t Count __attribute__((unused)))
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,15 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
/*
|
/**
|
||||||
report result of decimal operation
|
report result of decimal operation.
|
||||||
|
|
||||||
SYNOPSIS
|
@param result decimal library return code (E_DEC_* see include/decimal.h)
|
||||||
decimal_operation_results()
|
|
||||||
result decimal library return code (E_DEC_* see include/decimal.h)
|
|
||||||
|
|
||||||
TODO
|
@todo
|
||||||
Fix error messages
|
Fix error messages
|
||||||
|
|
||||||
RETURN
|
@return
|
||||||
result
|
result
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
It is interface module to fixed precision decimals library.
|
It is interface module to fixed precision decimals library.
|
||||||
|
|
||||||
Most functions use 'uint mask' as parameter, if during operation error
|
Most functions use 'uint mask' as parameter, if during operation error
|
||||||
|
|
@ -34,14 +36,14 @@ C_MODE_END
|
||||||
#define DECIMAL_LONG_DIGITS 10
|
#define DECIMAL_LONG_DIGITS 10
|
||||||
#define DECIMAL_LONG3_DIGITS 8
|
#define DECIMAL_LONG3_DIGITS 8
|
||||||
|
|
||||||
/* maximum length of buffer in our big digits (uint32) */
|
/** maximum length of buffer in our big digits (uint32). */
|
||||||
#define DECIMAL_BUFF_LENGTH 9
|
#define DECIMAL_BUFF_LENGTH 9
|
||||||
|
|
||||||
/* the number of digits that my_decimal can possibly contain */
|
/* the number of digits that my_decimal can possibly contain */
|
||||||
#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
|
#define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
maximum guaranteed precision of number in decimal digits (number of our
|
maximum guaranteed precision of number in decimal digits (number of our
|
||||||
digits * number of decimal digits in one our big digit - number of decimal
|
digits * number of decimal digits in one our big digit - number of decimal
|
||||||
digits in one our big digit decreased by 1 (because we always put decimal
|
digits in one our big digit decreased by 1 (because we always put decimal
|
||||||
|
|
@ -51,13 +53,14 @@ C_MODE_END
|
||||||
#define DECIMAL_MAX_SCALE 30
|
#define DECIMAL_MAX_SCALE 30
|
||||||
#define DECIMAL_NOT_SPECIFIED 31
|
#define DECIMAL_NOT_SPECIFIED 31
|
||||||
|
|
||||||
/*
|
/**
|
||||||
maximum length of string representation (number of maximum decimal
|
maximum length of string representation (number of maximum decimal
|
||||||
digits + 1 position for sign + 1 position for decimal point)
|
digits + 1 position for sign + 1 position for decimal point)
|
||||||
*/
|
*/
|
||||||
#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
|
#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
|
||||||
/*
|
|
||||||
maximum size of packet length
|
/**
|
||||||
|
maximum size of packet length.
|
||||||
*/
|
*/
|
||||||
#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
|
#define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION
|
||||||
|
|
||||||
|
|
@ -78,11 +81,12 @@ inline int my_decimal_int_part(uint precision, uint decimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
my_decimal class limits 'decimal_t' type to what we need in MySQL
|
my_decimal class limits 'decimal_t' type to what we need in MySQL.
|
||||||
|
|
||||||
It contains internally all necessary space needed by the instance so
|
It contains internally all necessary space needed by the instance so
|
||||||
no extra memory is needed. One should call fix_buffer_pointer() function
|
no extra memory is needed. One should call fix_buffer_pointer() function
|
||||||
when he moves my_decimal objects in memory
|
when he moves my_decimal objects in memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class my_decimal :public decimal_t
|
class my_decimal :public decimal_t
|
||||||
|
|
@ -384,7 +388,10 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Returns -1 if a<b, 1 if a>b and 0 if a==b */
|
/**
|
||||||
|
@return
|
||||||
|
-1 if a<b, 1 if a>b and 0 if a==b
|
||||||
|
*/
|
||||||
inline
|
inline
|
||||||
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,13 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@details
|
||||||
Mostly this file is used in the server. But a little part of it is used in
|
Mostly this file is used in the server. But a little part of it is used in
|
||||||
mysqlbinlog too (definition of SELECT_DISTINCT and others).
|
mysqlbinlog too (definition of SELECT_DISTINCT and others).
|
||||||
The consequence is that 90% of the file is wrapped in #ifndef MYSQL_CLIENT,
|
The consequence is that 90% of the file is wrapped in \#ifndef MYSQL_CLIENT,
|
||||||
except the part which must be in the server and in the client.
|
except the part which must be in the server and in the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -253,12 +256,12 @@ protected:
|
||||||
Feel free to raise this by the smallest amount you can to get the
|
Feel free to raise this by the smallest amount you can to get the
|
||||||
"execution_constants" test to pass.
|
"execution_constants" test to pass.
|
||||||
*/
|
*/
|
||||||
#define STACK_MIN_SIZE 12000 // Abort if less stack during eval.
|
#define STACK_MIN_SIZE 12000 ///< Abort if less stack during eval.
|
||||||
|
|
||||||
#define STACK_MIN_SIZE_FOR_OPEN 1024*80
|
#define STACK_MIN_SIZE_FOR_OPEN 1024*80
|
||||||
#define STACK_BUFF_ALLOC 352 // For stack overrun checks
|
#define STACK_BUFF_ALLOC 352 ///< For stack overrun checks
|
||||||
#ifndef MYSQLD_NET_RETRY_COUNT
|
#ifndef MYSQLD_NET_RETRY_COUNT
|
||||||
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
|
#define MYSQLD_NET_RETRY_COUNT 10 ///< Abort read after this many int.
|
||||||
#endif
|
#endif
|
||||||
#define TEMP_POOL_SIZE 128
|
#define TEMP_POOL_SIZE 128
|
||||||
|
|
||||||
|
|
@ -282,14 +285,14 @@ protected:
|
||||||
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
|
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
|
||||||
#define MIN_ROWS_TO_USE_BULK_INSERT 100
|
#define MIN_ROWS_TO_USE_BULK_INSERT 100
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The following is used to decide if MySQL should use table scanning
|
The following is used to decide if MySQL should use table scanning
|
||||||
instead of reading with keys. The number says how many evaluation of the
|
instead of reading with keys. The number says how many evaluation of the
|
||||||
WHERE clause is comparable to reading one extra row from a table.
|
WHERE clause is comparable to reading one extra row from a table.
|
||||||
*/
|
*/
|
||||||
#define TIME_FOR_COMPARE 5 // 5 compares == one read
|
#define TIME_FOR_COMPARE 5 // 5 compares == one read
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Number of comparisons of table rowids equivalent to reading one row from a
|
Number of comparisons of table rowids equivalent to reading one row from a
|
||||||
table.
|
table.
|
||||||
*/
|
*/
|
||||||
|
|
@ -309,17 +312,17 @@ protected:
|
||||||
#define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK)
|
#define DISK_SEEK_PROP_COST ((double)0.5/BLOCKS_IN_AVG_SEEK)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Number of rows in a reference table when refereed through a not unique key.
|
Number of rows in a reference table when refereed through a not unique key.
|
||||||
This value is only used when we don't know anything about the key
|
This value is only used when we don't know anything about the key
|
||||||
distribution.
|
distribution.
|
||||||
*/
|
*/
|
||||||
#define MATCHING_ROWS_IN_OTHER_TABLE 10
|
#define MATCHING_ROWS_IN_OTHER_TABLE 10
|
||||||
|
|
||||||
/* Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used) */
|
/** Don't pack string keys shorter than this (if PACK_KEYS=1 isn't used). */
|
||||||
#define KEY_DEFAULT_PACK_LENGTH 8
|
#define KEY_DEFAULT_PACK_LENGTH 8
|
||||||
|
|
||||||
/* Characters shown for the command in 'show processlist' */
|
/** Characters shown for the command in 'show processlist'. */
|
||||||
#define PROCESS_LIST_WIDTH 100
|
#define PROCESS_LIST_WIDTH 100
|
||||||
/* Characters shown for the command in 'information_schema.processlist' */
|
/* Characters shown for the command in 'information_schema.processlist' */
|
||||||
#define PROCESS_LIST_INFO_WIDTH 65535
|
#define PROCESS_LIST_INFO_WIDTH 65535
|
||||||
|
|
@ -335,11 +338,11 @@ protected:
|
||||||
|
|
||||||
/* The following can also be changed from the command line */
|
/* The following can also be changed from the command line */
|
||||||
#define DEFAULT_CONCURRENCY 10
|
#define DEFAULT_CONCURRENCY 10
|
||||||
#define DELAYED_LIMIT 100 /* pause after xxx inserts */
|
#define DELAYED_LIMIT 100 /**< pause after xxx inserts */
|
||||||
#define DELAYED_QUEUE_SIZE 1000
|
#define DELAYED_QUEUE_SIZE 1000
|
||||||
#define DELAYED_WAIT_TIMEOUT 5*60 /* Wait for delayed insert */
|
#define DELAYED_WAIT_TIMEOUT 5*60 /**< Wait for delayed insert */
|
||||||
#define FLUSH_TIME 0 /* Don't flush tables */
|
#define FLUSH_TIME 0 /**< Don't flush tables */
|
||||||
#define MAX_CONNECT_ERRORS 10 // errors before disabling host
|
#define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
|
||||||
|
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
#define IF_NETWARE(A,B) A
|
#define IF_NETWARE(A,B) A
|
||||||
|
|
@ -349,7 +352,7 @@ protected:
|
||||||
|
|
||||||
#if defined(__WIN__)
|
#if defined(__WIN__)
|
||||||
#undef FLUSH_TIME
|
#undef FLUSH_TIME
|
||||||
#define FLUSH_TIME 1800 /* Flush every half hour */
|
#define FLUSH_TIME 1800 /**< Flush every half hour */
|
||||||
|
|
||||||
#define INTERRUPT_PRIOR -2
|
#define INTERRUPT_PRIOR -2
|
||||||
#define CONNECT_PRIOR -1
|
#define CONNECT_PRIOR -1
|
||||||
|
|
@ -368,12 +371,12 @@ protected:
|
||||||
#define TEST_MIT_THREAD 4
|
#define TEST_MIT_THREAD 4
|
||||||
#define TEST_BLOCKING 8
|
#define TEST_BLOCKING 8
|
||||||
#define TEST_KEEP_TMP_TABLES 16
|
#define TEST_KEEP_TMP_TABLES 16
|
||||||
#define TEST_READCHECK 64 /* Force use of readcheck */
|
#define TEST_READCHECK 64 /**< Force use of readcheck */
|
||||||
#define TEST_NO_EXTRA 128
|
#define TEST_NO_EXTRA 128
|
||||||
#define TEST_CORE_ON_SIGNAL 256 /* Give core if signal */
|
#define TEST_CORE_ON_SIGNAL 256 /**< Give core if signal */
|
||||||
#define TEST_NO_STACKTRACE 512
|
#define TEST_NO_STACKTRACE 512
|
||||||
#define TEST_SIGINT 1024 /* Allow sigint on threads */
|
#define TEST_SIGINT 1024 /**< Allow sigint on threads */
|
||||||
#define TEST_SYNCHRONIZATION 2048 /* get server to do sleep in
|
#define TEST_SYNCHRONIZATION 2048 /**< get server to do sleep in
|
||||||
some places */
|
some places */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -423,26 +426,26 @@ protected:
|
||||||
/* The following is used to detect a conflict with DISTINCT */
|
/* The following is used to detect a conflict with DISTINCT */
|
||||||
#define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser
|
#define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser
|
||||||
|
|
||||||
/* The following can be set when importing tables in a 'wrong order'
|
/** The following can be set when importing tables in a 'wrong order'
|
||||||
to suppress foreign key checks */
|
to suppress foreign key checks */
|
||||||
#define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog
|
#define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog
|
||||||
/* The following speeds up inserts to InnoDB tables by suppressing unique
|
/** The following speeds up inserts to InnoDB tables by suppressing unique
|
||||||
key checks in some cases */
|
key checks in some cases */
|
||||||
#define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog
|
#define OPTION_RELAXED_UNIQUE_CHECKS (ULL(1) << 27) // THD, user, binlog
|
||||||
#define SELECT_NO_UNLOCK (ULL(1) << 28) // SELECT, intern
|
#define SELECT_NO_UNLOCK (ULL(1) << 28) // SELECT, intern
|
||||||
#define OPTION_SCHEMA_TABLE (ULL(1) << 29) // SELECT, intern
|
#define OPTION_SCHEMA_TABLE (ULL(1) << 29) // SELECT, intern
|
||||||
/* Flag set if setup_tables already done */
|
/** Flag set if setup_tables already done */
|
||||||
#define OPTION_SETUP_TABLES_DONE (ULL(1) << 30) // intern
|
#define OPTION_SETUP_TABLES_DONE (ULL(1) << 30) // intern
|
||||||
/* If not set then the thread will ignore all warnings with level notes. */
|
/** If not set then the thread will ignore all warnings with level notes. */
|
||||||
#define OPTION_SQL_NOTES (ULL(1) << 31) // THD, user
|
#define OPTION_SQL_NOTES (ULL(1) << 31) // THD, user
|
||||||
/*
|
/**
|
||||||
Force the used temporary table to be a MyISAM table (because we will use
|
Force the used temporary table to be a MyISAM table (because we will use
|
||||||
fulltext functions when reading from it.
|
fulltext functions when reading from it.
|
||||||
*/
|
*/
|
||||||
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
|
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Maximum length of time zone name that we support
|
Maximum length of time zone name that we support
|
||||||
(Time zone name is char(64) in db). mysqlbinlog needs it.
|
(Time zone name is char(64) in db). mysqlbinlog needs it.
|
||||||
*/
|
*/
|
||||||
|
|
@ -505,9 +508,9 @@ protected:
|
||||||
#define UNCACHEABLE_DEPENDENT 1
|
#define UNCACHEABLE_DEPENDENT 1
|
||||||
#define UNCACHEABLE_RAND 2
|
#define UNCACHEABLE_RAND 2
|
||||||
#define UNCACHEABLE_SIDEEFFECT 4
|
#define UNCACHEABLE_SIDEEFFECT 4
|
||||||
// forcing to save JOIN for explain
|
/// forcing to save JOIN for explain
|
||||||
#define UNCACHEABLE_EXPLAIN 8
|
#define UNCACHEABLE_EXPLAIN 8
|
||||||
/* Don't evaluate subqueries in prepare even if they're not correlated */
|
/** Don't evaluate subqueries in prepare even if they're not correlated */
|
||||||
#define UNCACHEABLE_PREPARE 16
|
#define UNCACHEABLE_PREPARE 16
|
||||||
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
|
/* For uncorrelated SELECT in an UNION with some correlated SELECTs */
|
||||||
#define UNCACHEABLE_UNITED 32
|
#define UNCACHEABLE_UNITED 32
|
||||||
|
|
@ -515,7 +518,7 @@ protected:
|
||||||
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
|
/* Used to check GROUP BY list in the MODE_ONLY_FULL_GROUP_BY mode */
|
||||||
#define UNDEF_POS (-1)
|
#define UNDEF_POS (-1)
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
/*
|
/**
|
||||||
Sync points allow us to force the server to reach a certain line of code
|
Sync points allow us to force the server to reach a certain line of code
|
||||||
and block there until the client tells the server it is ok to go on.
|
and block there until the client tells the server it is ok to go on.
|
||||||
The client tells the server to block with SELECT GET_LOCK()
|
The client tells the server to block with SELECT GET_LOCK()
|
||||||
|
|
@ -551,7 +554,7 @@ void view_store_options(THD *thd, TABLE_LIST *table, String *buff);
|
||||||
|
|
||||||
#define portable_sizeof_char_ptr 8
|
#define portable_sizeof_char_ptr 8
|
||||||
|
|
||||||
#define tmp_file_prefix "#sql" /* Prefix for tmp tables */
|
#define tmp_file_prefix "#sql" /**< Prefix for tmp tables */
|
||||||
#define tmp_file_prefix_length 4
|
#define tmp_file_prefix_length 4
|
||||||
|
|
||||||
/* Flags for calc_week() function. */
|
/* Flags for calc_week() function. */
|
||||||
|
|
@ -586,9 +589,9 @@ enum enum_check_fields
|
||||||
CHECK_FIELD_WARN,
|
CHECK_FIELD_WARN,
|
||||||
CHECK_FIELD_ERROR_FOR_NULL
|
CHECK_FIELD_ERROR_FOR_NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Struct to handle simple linked lists */
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Struct to handle simple linked lists. */
|
||||||
typedef struct st_sql_list {
|
typedef struct st_sql_list {
|
||||||
uint elements;
|
uint elements;
|
||||||
uchar *first;
|
uchar *first;
|
||||||
|
|
@ -2209,16 +2212,15 @@ Item * all_any_subquery_creator(Item *left_expr,
|
||||||
bool all,
|
bool all,
|
||||||
SELECT_LEX *select_lex);
|
SELECT_LEX *select_lex);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
clean/setup table fields and map
|
clean/setup table fields and map.
|
||||||
|
|
||||||
SYNOPSYS
|
@param table TABLE structure pointer (which should be setup)
|
||||||
setup_table_map()
|
@param table_list TABLE_LIST structure pointer (owner of TABLE)
|
||||||
table - TABLE structure pointer (which should be setup)
|
@param tablenr table number
|
||||||
table_list TABLE_LIST structure pointer (owner of TABLE)
|
|
||||||
tablenr - table number
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
||||||
{
|
{
|
||||||
table->used_fields= 0;
|
table->used_fields= 0;
|
||||||
|
|
@ -2240,10 +2242,8 @@ inline void setup_table_map(TABLE *table, TABLE_LIST *table_list, uint tablenr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
SYNOPSYS
|
convert a hex digit into number.
|
||||||
hexchar_to_int()
|
|
||||||
convert a hex digit into number
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline int hexchar_to_int(char c)
|
inline int hexchar_to_int(char c)
|
||||||
|
|
@ -2256,11 +2256,9 @@ inline int hexchar_to_int(char c)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
is_user_table()
|
return true if the table was created explicitly.
|
||||||
return true if the table was created explicitly
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
inline bool is_user_table(TABLE * table)
|
inline bool is_user_table(TABLE * table)
|
||||||
{
|
{
|
||||||
const char *name= table->s->table_name.str;
|
const char *name= table->s->table_name.str;
|
||||||
|
|
|
||||||
248
sql/mysqld.cc
248
sql/mysqld.cc
|
|
@ -170,10 +170,10 @@ int initgroups(const char *,unsigned int);
|
||||||
typedef fp_except fp_except_t;
|
typedef fp_except fp_except_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We can't handle floating point exceptions with threads, so disable
|
/**
|
||||||
this on freebsd
|
We can't handle floating point exceptions with threads, so disable
|
||||||
*/
|
this on freebsd.
|
||||||
|
*/
|
||||||
inline void reset_floating_point_exceptions()
|
inline void reset_floating_point_exceptions()
|
||||||
{
|
{
|
||||||
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
|
/* Don't fall for overflow, underflow,divide-by-zero or loss of precision */
|
||||||
|
|
@ -325,7 +325,7 @@ static my_bool opt_short_log_format= 0;
|
||||||
static uint kill_cached_threads, wake_thread;
|
static uint kill_cached_threads, wake_thread;
|
||||||
static ulong killed_threads, thread_created;
|
static ulong killed_threads, thread_created;
|
||||||
static ulong max_used_connections;
|
static ulong max_used_connections;
|
||||||
static ulong my_bind_addr; /* the address we bind to */
|
static ulong my_bind_addr; /**< the address we bind to */
|
||||||
static volatile ulong cached_thread_count= 0;
|
static volatile ulong cached_thread_count= 0;
|
||||||
static const char *sql_mode_str= "OFF";
|
static const char *sql_mode_str= "OFF";
|
||||||
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
|
||||||
|
|
@ -366,7 +366,7 @@ bool volatile shutdown_in_progress;
|
||||||
*/
|
*/
|
||||||
bool volatile grant_option;
|
bool volatile grant_option;
|
||||||
|
|
||||||
my_bool opt_skip_slave_start = 0; // If set, slave is not autostarted
|
my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
|
||||||
my_bool opt_reckless_slave = 0;
|
my_bool opt_reckless_slave = 0;
|
||||||
my_bool opt_enable_named_pipe= 0;
|
my_bool opt_enable_named_pipe= 0;
|
||||||
my_bool opt_local_infile, opt_slave_compressed_protocol;
|
my_bool opt_local_infile, opt_slave_compressed_protocol;
|
||||||
|
|
@ -430,7 +430,7 @@ TYPELIB binlog_format_typelib=
|
||||||
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
|
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
|
||||||
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
|
||||||
#ifdef HAVE_INITGROUPS
|
#ifdef HAVE_INITGROUPS
|
||||||
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
|
static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
|
||||||
#endif
|
#endif
|
||||||
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
|
||||||
uint mysqld_port_timeout;
|
uint mysqld_port_timeout;
|
||||||
|
|
@ -458,12 +458,12 @@ ulong specialflag=0;
|
||||||
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
|
||||||
ulong max_connections, max_connect_errors;
|
ulong max_connections, max_connect_errors;
|
||||||
uint max_user_connections= 0;
|
uint max_user_connections= 0;
|
||||||
/*
|
/**
|
||||||
Limit of the total number of prepared statements in the server.
|
Limit of the total number of prepared statements in the server.
|
||||||
Is necessary to protect the server against out-of-memory attacks.
|
Is necessary to protect the server against out-of-memory attacks.
|
||||||
*/
|
*/
|
||||||
ulong max_prepared_stmt_count;
|
ulong max_prepared_stmt_count;
|
||||||
/*
|
/**
|
||||||
Current total number of prepared statements in the server. This number
|
Current total number of prepared statements in the server. This number
|
||||||
is exact, and therefore may not be equal to the difference between
|
is exact, and therefore may not be equal to the difference between
|
||||||
`com_stmt_prepare' and `com_stmt_close' (global status variables), as
|
`com_stmt_prepare' and `com_stmt_close' (global status variables), as
|
||||||
|
|
@ -499,13 +499,13 @@ uint mysql_data_home_len;
|
||||||
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
|
char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
|
||||||
char server_version[SERVER_VERSION_LENGTH];
|
char server_version[SERVER_VERSION_LENGTH];
|
||||||
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
char *mysqld_unix_port, *opt_mysql_tmpdir;
|
||||||
const char **errmesg; /* Error messages */
|
const char **errmesg; /**< Error messages */
|
||||||
const char *myisam_recover_options_str="OFF";
|
const char *myisam_recover_options_str="OFF";
|
||||||
const char *myisam_stats_method_str="nulls_unequal";
|
const char *myisam_stats_method_str="nulls_unequal";
|
||||||
|
|
||||||
/* name of reference on left espression in rewritten IN subquery */
|
/** name of reference on left espression in rewritten IN subquery */
|
||||||
const char *in_left_expr_name= "<left expr>";
|
const char *in_left_expr_name= "<left expr>";
|
||||||
/* name of additional condition */
|
/** name of additional condition */
|
||||||
const char *in_additional_cond= "<IN COND>";
|
const char *in_additional_cond= "<IN COND>";
|
||||||
const char *in_having_cond= "<IN HAVING>";
|
const char *in_having_cond= "<IN HAVING>";
|
||||||
|
|
||||||
|
|
@ -555,7 +555,7 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
||||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||||
LOCK_global_system_variables,
|
LOCK_global_system_variables,
|
||||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||||
/*
|
/**
|
||||||
The below lock protects access to two global server variables:
|
The below lock protects access to two global server variables:
|
||||||
max_prepared_stmt_count and prepared_stmt_count. These variables
|
max_prepared_stmt_count and prepared_stmt_count. These variables
|
||||||
set the limit and hold the current total number of prepared statements
|
set the limit and hold the current total number of prepared statements
|
||||||
|
|
@ -604,7 +604,7 @@ static char **defaults_argv;
|
||||||
static char *opt_bin_logname;
|
static char *opt_bin_logname;
|
||||||
|
|
||||||
static my_socket unix_sock,ip_sock;
|
static my_socket unix_sock,ip_sock;
|
||||||
struct rand_struct sql_rand; // used by sql_class.cc:THD::THD()
|
struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
struct passwd *user_info;
|
struct passwd *user_info;
|
||||||
|
|
@ -628,7 +628,7 @@ static char **opt_argv;
|
||||||
static HANDLE hEventShutdown;
|
static HANDLE hEventShutdown;
|
||||||
static char shutdown_event_name[40];
|
static char shutdown_event_name[40];
|
||||||
#include "nt_servc.h"
|
#include "nt_servc.h"
|
||||||
static NTService Service; // Service object for WinNT
|
static NTService Service; ///< Service object for WinNT
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
|
|
@ -1009,19 +1009,15 @@ void kill_mysql(void)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Force server down. Kill all connections and threads and exit
|
Force server down. Kill all connections and threads and exit.
|
||||||
|
|
||||||
SYNOPSIS
|
@param sig_ptr Signal number that caused kill_server to be called.
|
||||||
kill_server
|
|
||||||
|
|
||||||
sig_ptr Signal number that caused kill_server to be called.
|
@note
|
||||||
|
|
||||||
NOTE!
|
|
||||||
A signal number of 0 mean that the function was not called
|
A signal number of 0 mean that the function was not called
|
||||||
from a signal handler and there is thus no signal to block
|
from a signal handler and there is thus no signal to block
|
||||||
or stop, we just want to kill the server.
|
or stop, we just want to kill the server.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__NETWARE__)
|
#if defined(__NETWARE__)
|
||||||
|
|
@ -1114,21 +1110,18 @@ extern "C" sig_handler print_signal_warning(int sig)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef EMBEDDED_LIBRARY
|
||||||
cleanup all memory and end program nicely
|
|
||||||
|
|
||||||
SYNOPSIS
|
/**
|
||||||
unireg_end()
|
cleanup all memory and end program nicely.
|
||||||
|
|
||||||
NOTES
|
|
||||||
This function never returns.
|
|
||||||
|
|
||||||
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
If SIGNALS_DONT_BREAK_READ is defined, this function is called
|
||||||
by the main thread. To get MySQL to shut down nicely in this case
|
by the main thread. To get MySQL to shut down nicely in this case
|
||||||
(Mac OS X) we have to call exit() instead if pthread_exit().
|
(Mac OS X) we have to call exit() instead if pthread_exit().
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
@note
|
||||||
|
This function never returns.
|
||||||
|
*/
|
||||||
void unireg_end(void)
|
void unireg_end(void)
|
||||||
{
|
{
|
||||||
clean_up(1);
|
clean_up(1);
|
||||||
|
|
@ -1275,11 +1268,10 @@ void clean_up(bool print_message)
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This is mainly needed when running with purify, but it's still nice to
|
This is mainly needed when running with purify, but it's still nice to
|
||||||
know that all child threads have died when mysqld exits
|
know that all child threads have died when mysqld exits.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void wait_for_signal_thread_to_end()
|
static void wait_for_signal_thread_to_end()
|
||||||
{
|
{
|
||||||
#ifndef __NETWARE__
|
#ifndef __NETWARE__
|
||||||
|
|
@ -1506,8 +1498,7 @@ static void set_effective_user(struct passwd *user_info_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Change root user if started with --chroot */
|
/** Change root user if started with @c --chroot . */
|
||||||
|
|
||||||
static void set_root(const char *path)
|
static void set_root(const char *path)
|
||||||
{
|
{
|
||||||
#if !defined(__WIN__) && !defined(__NETWARE__)
|
#if !defined(__WIN__) && !defined(__NETWARE__)
|
||||||
|
|
@ -1696,19 +1687,16 @@ static void network_init(void)
|
||||||
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
/*
|
/**
|
||||||
Close a connection
|
Close a connection.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handle
|
||||||
close_connection()
|
@param errcode Error code to print to console
|
||||||
thd Thread handle
|
@param lock 1 if we have have to lock LOCK_thread_count
|
||||||
errcode Error code to print to console
|
|
||||||
lock 1 if we have have to lock LOCK_thread_count
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
For the connection that is doing shutdown, this is called twice
|
For the connection that is doing shutdown, this is called twice
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void close_connection(THD *thd, uint errcode, bool lock)
|
void close_connection(THD *thd, uint errcode, bool lock)
|
||||||
{
|
{
|
||||||
st_vio *vio;
|
st_vio *vio;
|
||||||
|
|
@ -1733,9 +1721,8 @@ void close_connection(THD *thd, uint errcode, bool lock)
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
/* Called when a thread is aborted */
|
/** Called when a thread is aborted. */
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
|
||||||
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
|
||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
|
|
@ -1877,13 +1864,13 @@ void flush_thread_cache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Aborts a thread nicely. Commes here on SIGPIPE
|
|
||||||
TODO: One should have to fix that thr_alarm know about this
|
|
||||||
thread too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||||
|
/**
|
||||||
|
Aborts a thread nicely. Comes here on SIGPIPE.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
One should have to fix that thr_alarm know about this thread too.
|
||||||
|
*/
|
||||||
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
|
||||||
{
|
{
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
|
|
@ -1931,7 +1918,7 @@ static void check_data_home(const char *path)
|
||||||
|
|
||||||
#elif defined(__NETWARE__)
|
#elif defined(__NETWARE__)
|
||||||
|
|
||||||
// down server event callback
|
/// down server event callback.
|
||||||
void mysql_down_server_cb(void *, void *)
|
void mysql_down_server_cb(void *, void *)
|
||||||
{
|
{
|
||||||
event_flag= TRUE;
|
event_flag= TRUE;
|
||||||
|
|
@ -1939,7 +1926,7 @@ void mysql_down_server_cb(void *, void *)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destroy callback resources
|
/// destroy callback resources.
|
||||||
void mysql_cb_destroy(void *)
|
void mysql_cb_destroy(void *)
|
||||||
{
|
{
|
||||||
UnRegisterEventNotification(eh); // cleanup down event notification
|
UnRegisterEventNotification(eh); // cleanup down event notification
|
||||||
|
|
@ -1951,7 +1938,7 @@ void mysql_cb_destroy(void *)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// initialize callbacks
|
/// initialize callbacks.
|
||||||
void mysql_cb_init()
|
void mysql_cb_init()
|
||||||
{
|
{
|
||||||
// register for down server event
|
// register for down server event
|
||||||
|
|
@ -1974,8 +1961,7 @@ void mysql_cb_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* To get the name of the NetWare volume having MySQL data folder */
|
/** To get the name of the NetWare volume having MySQL data folder. */
|
||||||
|
|
||||||
static void getvolumename()
|
static void getvolumename()
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
@ -1989,8 +1975,8 @@ static void getvolumename()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Registering with NEB for NSS Volume Deactivation event
|
Registering with NEB for NSS Volume Deactivation event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void registerwithneb()
|
static void registerwithneb()
|
||||||
|
|
@ -2042,8 +2028,8 @@ static void registerwithneb()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Callback for NSS Volume Deactivation event
|
Callback for NSS Volume Deactivation event.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulong neb_event_callback(struct EventBlock *eblock)
|
ulong neb_event_callback(struct EventBlock *eblock)
|
||||||
|
|
@ -2075,12 +2061,11 @@ ulong neb_event_callback(struct EventBlock *eblock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function to get NSS volume ID of the MySQL data
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
|
#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Function to get NSS volume ID of the MySQL data.
|
||||||
|
*/
|
||||||
static void getvolumeID(BYTE *volumeName)
|
static void getvolumeID(BYTE *volumeName)
|
||||||
{
|
{
|
||||||
char path[zMAX_FULL_NAME];
|
char path[zMAX_FULL_NAME];
|
||||||
|
|
@ -2155,10 +2140,10 @@ static void start_signal_handler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Warn if the data is on a Traditional volume
|
Warn if the data is on a Traditional volume.
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
Already done by mysqld_safe
|
Already done by mysqld_safe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2419,8 +2404,7 @@ static void start_signal_handler(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This threads handles all signals and alarms */
|
/** This threads handles all signals and alarms. */
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
pthread_handler_t signal_hand(void *arg __attribute__((unused)))
|
||||||
{
|
{
|
||||||
|
|
@ -2558,12 +2542,10 @@ static void check_data_home(const char *path)
|
||||||
#endif /* __WIN__*/
|
#endif /* __WIN__*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
All global error messages are sent here where the first one is stored
|
All global error messages are sent here where the first one is stored
|
||||||
for the client
|
for the client.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
|
extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
|
||||||
|
|
||||||
|
|
@ -2694,20 +2676,19 @@ sizeof(load_default_groups)/sizeof(load_default_groups[0]);
|
||||||
#endif /*!EMBEDDED_LIBRARY*/
|
#endif /*!EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize one of the global date/time format variables
|
Initialize one of the global date/time format variables.
|
||||||
|
|
||||||
SYNOPSIS
|
@param format_type What kind of format should be supported
|
||||||
init_global_datetime_format()
|
@param var_ptr Pointer to variable that should be updated
|
||||||
format_type What kind of format should be supported
|
|
||||||
var_ptr Pointer to variable that should be updated
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The default value is taken from either opt_date_time_formats[] or
|
The default value is taken from either opt_date_time_formats[] or
|
||||||
the ISO format (ANSI SQL)
|
the ISO format (ANSI SQL)
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4050,21 +4031,20 @@ static char *add_quoted_string(char *to, const char *from, char *to_end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Handle basic handling of services, like installation and removal
|
Handle basic handling of services, like installation and removal.
|
||||||
|
|
||||||
SYNOPSIS
|
@param argv Pointer to argument list
|
||||||
default_service_handling()
|
@param servicename Internal name of service
|
||||||
argv Pointer to argument list
|
@param displayname Display name of service (in taskbar ?)
|
||||||
servicename Internal name of service
|
@param file_path Path to this program
|
||||||
displayname Display name of service (in taskbar ?)
|
@param startup_option Startup option to mysqld
|
||||||
file_path Path to this program
|
|
||||||
startup_option Startup option to mysqld
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 option handled
|
0 option handled
|
||||||
|
@retval
|
||||||
1 Could not handle option
|
1 Could not handle option
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
default_service_handling(char **argv,
|
default_service_handling(char **argv,
|
||||||
|
|
@ -4213,7 +4193,7 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute all commands from a file. Used by the mysql_install_db script to
|
Execute all commands from a file. Used by the mysql_install_db script to
|
||||||
create MySQL privilege tables without having to start a full MySQL server.
|
create MySQL privilege tables without having to start a full MySQL server.
|
||||||
*/
|
*/
|
||||||
|
|
@ -4342,23 +4322,17 @@ void create_thread_to_handle_connection(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create new thread to handle incoming connection.
|
Create new thread to handle incoming connection.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
create_new_thread()
|
|
||||||
thd in/out Thread handle of future thread.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
This function will create new thread to handle the incoming
|
This function will create new thread to handle the incoming
|
||||||
connection. If there are idle cached threads one will be used.
|
connection. If there are idle cached threads one will be used.
|
||||||
'thd' will be pushed into 'threads'.
|
'thd' will be pushed into 'threads'.
|
||||||
|
|
||||||
In single-threaded mode (#define ONE_THREAD) connection will be
|
In single-threaded mode (\#define ONE_THREAD) connection will be
|
||||||
handled inside this function.
|
handled inside this function.
|
||||||
|
|
||||||
RETURN VALUE
|
@param[in,out] thd Thread handle of future thread.
|
||||||
none
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void create_new_thread(THD *thd)
|
static void create_new_thread(THD *thd)
|
||||||
|
|
@ -4712,15 +4686,13 @@ pthread_handler_t handle_connections_namedpipes(void *arg)
|
||||||
#endif /* __NT__ */
|
#endif /* __NT__ */
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Thread of shared memory's service
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
handle_connections_shared_memory()
|
|
||||||
arg Arguments of thread
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_SMEM
|
#ifdef HAVE_SMEM
|
||||||
|
|
||||||
|
/**
|
||||||
|
Thread of shared memory's service.
|
||||||
|
|
||||||
|
@param arg Arguments of thread
|
||||||
|
*/
|
||||||
pthread_handler_t handle_connections_shared_memory(void *arg)
|
pthread_handler_t handle_connections_shared_memory(void *arg)
|
||||||
{
|
{
|
||||||
/* file-mapping object, use for create shared memory */
|
/* file-mapping object, use for create shared memory */
|
||||||
|
|
@ -7052,13 +7024,13 @@ To see what values a running MySQL server is using, type\n\
|
||||||
#endif /*!EMBEDDED_LIBRARY*/
|
#endif /*!EMBEDDED_LIBRARY*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize all MySQL global variables to default values
|
Initialize all MySQL global variables to default values.
|
||||||
|
|
||||||
SYNOPSIS
|
We don't need to set numeric variables refered to in my_long_options
|
||||||
mysql_init_variables()
|
as these are initialized by my_getopt.
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
The reason to set a lot of global variables to zero is to allow one to
|
The reason to set a lot of global variables to zero is to allow one to
|
||||||
restart the embedded server with a clean environment
|
restart the embedded server with a clean environment
|
||||||
It's also needed on some exotic platforms where global variables are
|
It's also needed on some exotic platforms where global variables are
|
||||||
|
|
@ -7785,7 +7757,7 @@ mysqld_get_one_option(int optid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handle arguments for multiple key caches */
|
/** Handle arguments for multiple key caches. */
|
||||||
|
|
||||||
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
|
extern "C" uchar **mysql_getopt_value(const char *keyname, uint key_length,
|
||||||
const struct my_option *option);
|
const struct my_option *option);
|
||||||
|
|
@ -7836,6 +7808,10 @@ void option_error_reporter(enum loglevel level, const char *format, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
- FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
|
||||||
|
*/
|
||||||
static void get_options(int *argc,char **argv)
|
static void get_options(int *argc,char **argv)
|
||||||
{
|
{
|
||||||
int ho_error;
|
int ho_error;
|
||||||
|
|
@ -7967,10 +7943,11 @@ static char *get_relative_path(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Fix filename and replace extension where 'dir' is relative to
|
Fix filename and replace extension where 'dir' is relative to
|
||||||
mysql_real_data_home.
|
mysql_real_data_home.
|
||||||
Return 1 if len(path) > FN_REFLEN
|
@return
|
||||||
|
1 if len(path) > FN_REFLEN
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -8075,9 +8052,11 @@ static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return a bitfield from a string of substrings separated by ','
|
@return
|
||||||
returns ~(ulong) 0 on error.
|
a bitfield from a string of substrings separated by ','
|
||||||
|
or
|
||||||
|
~(ulong) 0 on error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
|
static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
|
||||||
|
|
@ -8136,16 +8115,16 @@ skip: ;
|
||||||
} /* find_bit_type */
|
} /* find_bit_type */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if file system used for databases is case insensitive
|
Check if file system used for databases is case insensitive.
|
||||||
|
|
||||||
SYNOPSIS
|
@param dir_name Directory to test
|
||||||
test_if_case_sensitive()
|
|
||||||
dir_name Directory to test
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
-1 Don't know (Test failed)
|
-1 Don't know (Test failed)
|
||||||
|
@retval
|
||||||
0 File system is case sensitive
|
0 File system is case sensitive
|
||||||
|
@retval
|
||||||
1 File system is case insensitive
|
1 File system is case insensitive
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -8176,10 +8155,11 @@ static int test_if_case_insensitive(const char *dir_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create file to store pid number */
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create file to store pid number.
|
||||||
|
*/
|
||||||
static void create_pid_file()
|
static void create_pid_file()
|
||||||
{
|
{
|
||||||
File file;
|
File file;
|
||||||
|
|
@ -8201,7 +8181,7 @@ static void create_pid_file()
|
||||||
}
|
}
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
/* Clear most status variables */
|
/** Clear most status variables. */
|
||||||
void refresh_status(THD *thd)
|
void refresh_status(THD *thd)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&LOCK_status);
|
pthread_mutex_lock(&LOCK_status);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,11 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set MYSQL_SERVER_SUFFIX_STR
|
@file
|
||||||
|
|
||||||
|
Set MYSQL_SERVER_SUFFIX_STR.
|
||||||
|
|
||||||
The following code is quite ugly as there is no portable way to easily set a
|
The following code is quite ugly as there is no portable way to easily set a
|
||||||
string to the value of a macro
|
string to the value of a macro
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
This file is the net layer API for the MySQL client/server protocol,
|
This file is the net layer API for the MySQL client/server protocol,
|
||||||
which is a tightly coupled, proprietary protocol owned by MySQL AB.
|
which is a tightly coupled, proprietary protocol owned by MySQL AB.
|
||||||
|
@note
|
||||||
Any re-implementations of this protocol must also be under GPL
|
Any re-implementations of this protocol must also be under GPL
|
||||||
unless one has got an license from MySQL AB stating otherwise.
|
unless one has got an license from MySQL AB stating otherwise.
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
Write and read of logical packets to/from socket.
|
||||||
Write and read of logical packets to/from socket
|
|
||||||
|
|
||||||
Writes are cached into net_buffer_length big packets.
|
Writes are cached into net_buffer_length big packets.
|
||||||
Read packets are reallocated dynamicly when reading big packets.
|
Read packets are reallocated dynamicly when reading big packets.
|
||||||
|
|
@ -111,7 +112,7 @@ extern void query_cache_insert(NET *net, const char *packet, ulong length);
|
||||||
static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
|
static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
|
||||||
|
|
||||||
|
|
||||||
/* Init with packet info */
|
/** Init with packet info. */
|
||||||
|
|
||||||
my_bool my_net_init(NET *net, Vio* vio)
|
my_bool my_net_init(NET *net, Vio* vio)
|
||||||
{
|
{
|
||||||
|
|
@ -163,7 +164,7 @@ void net_end(NET *net)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Realloc the packet buffer */
|
/** Realloc the packet buffer. */
|
||||||
|
|
||||||
my_bool net_realloc(NET *net, size_t length)
|
my_bool net_realloc(NET *net, size_t length)
|
||||||
{
|
{
|
||||||
|
|
@ -201,20 +202,17 @@ my_bool net_realloc(NET *net, size_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if there is any data to be read from the socket
|
Check if there is any data to be read from the socket.
|
||||||
|
|
||||||
SYNOPSIS
|
@param sd socket descriptor
|
||||||
net_data_is_ready()
|
|
||||||
sd socket descriptor
|
|
||||||
|
|
||||||
DESCRIPTION
|
@retval
|
||||||
Check if there is any data to be read from the socket.
|
0 No data to read
|
||||||
|
@retval
|
||||||
RETURN VALUES
|
1 Data or EOF to read
|
||||||
0 No data to read
|
@retval
|
||||||
1 Data or EOF to read
|
-1 Don't know if data is ready or not
|
||||||
-1 Don't know if data is ready or not
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(EMBEDDED_LIBRARY)
|
#if !defined(EMBEDDED_LIBRARY)
|
||||||
|
|
@ -258,16 +256,10 @@ static int net_data_is_ready(my_socket sd)
|
||||||
|
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove unwanted characters from connection
|
Remove unwanted characters from connection
|
||||||
and check if disconnected
|
and check if disconnected.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
net_clear()
|
|
||||||
net NET handler
|
|
||||||
clear_buffer If <> 0, then clear all data from communication buffer
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Read from socket until there is nothing more to read. Discard
|
Read from socket until there is nothing more to read. Discard
|
||||||
what is read.
|
what is read.
|
||||||
|
|
||||||
|
|
@ -278,6 +270,8 @@ static int net_data_is_ready(my_socket sd)
|
||||||
a FIN packet), then select() considers a socket "ready to read",
|
a FIN packet), then select() considers a socket "ready to read",
|
||||||
in the sense that there's EOF to read, but read() returns 0.
|
in the sense that there's EOF to read, but read() returns 0.
|
||||||
|
|
||||||
|
@param net NET handler
|
||||||
|
@param clear_buffer if <> 0, then clear all data from comm buff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void net_clear(NET *net, my_bool clear_buffer)
|
void net_clear(NET *net, my_bool clear_buffer)
|
||||||
|
|
@ -335,7 +329,7 @@ void net_clear(NET *net, my_bool clear_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Flush write_buffer if not empty. */
|
/** Flush write_buffer if not empty. */
|
||||||
|
|
||||||
my_bool net_flush(NET *net)
|
my_bool net_flush(NET *net)
|
||||||
{
|
{
|
||||||
|
|
@ -358,12 +352,13 @@ my_bool net_flush(NET *net)
|
||||||
** Write something to server/client buffer
|
** Write something to server/client buffer
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Write a logical packet with packet header
|
Write a logical packet with packet header.
|
||||||
|
|
||||||
Format: Packet length (3 bytes), packet number(1 byte)
|
Format: Packet length (3 bytes), packet number(1 byte)
|
||||||
When compression is used a 3 byte compression length is added
|
When compression is used a 3 byte compression length is added
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
If compression is used the original package is modified!
|
If compression is used the original package is modified!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -400,19 +395,9 @@ my_net_write(NET *net,const uchar *packet,size_t len)
|
||||||
return test(net_write_buff(net,packet,len));
|
return test(net_write_buff(net,packet,len));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Send a command to the server.
|
Send a command to the server.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
net_write_command()
|
|
||||||
net NET handler
|
|
||||||
command Command in MySQL server (enum enum_server_command)
|
|
||||||
header Header to write after command
|
|
||||||
head_len Length of header
|
|
||||||
packet Query or parameter to query
|
|
||||||
len Length of packet
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
The reason for having both header and packet is so that libmysql
|
The reason for having both header and packet is so that libmysql
|
||||||
can easy add a header to a special command (like prepared statements)
|
can easy add a header to a special command (like prepared statements)
|
||||||
without having to re-alloc the string.
|
without having to re-alloc the string.
|
||||||
|
|
@ -420,11 +405,20 @@ my_net_write(NET *net,const uchar *packet,size_t len)
|
||||||
As the command is part of the first data packet, we have to do some data
|
As the command is part of the first data packet, we have to do some data
|
||||||
juggling to put the command in there, without having to create a new
|
juggling to put the command in there, without having to create a new
|
||||||
packet.
|
packet.
|
||||||
|
|
||||||
This function will split big packets into sub-packets if needed.
|
This function will split big packets into sub-packets if needed.
|
||||||
(Each sub packet can only be 2^24 bytes)
|
(Each sub packet can only be 2^24 bytes)
|
||||||
|
|
||||||
RETURN VALUES
|
@param net NET handler
|
||||||
|
@param command Command in MySQL server (enum enum_server_command)
|
||||||
|
@param header Header to write after command
|
||||||
|
@param head_len Length of header
|
||||||
|
@param packet Query or parameter to query
|
||||||
|
@param len Length of packet
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -468,33 +462,30 @@ net_write_command(NET *net,uchar command,
|
||||||
net_write_buff(net, packet, len) || net_flush(net)));
|
net_write_buff(net, packet, len) || net_flush(net)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Caching the data in a local buffer before sending it.
|
Caching the data in a local buffer before sending it.
|
||||||
|
|
||||||
SYNOPSIS
|
Fill up net->buffer and send it to the client when full.
|
||||||
net_write_buff()
|
|
||||||
net Network handler
|
|
||||||
packet Packet to send
|
|
||||||
len Length of packet
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Fill up net->buffer and send it to the client when full.
|
|
||||||
|
|
||||||
If the rest of the to-be-sent-packet is bigger than buffer,
|
If the rest of the to-be-sent-packet is bigger than buffer,
|
||||||
send it in one big block (to avoid copying to internal buffer).
|
send it in one big block (to avoid copying to internal buffer).
|
||||||
If not, copy the rest of the data to the buffer and return without
|
If not, copy the rest of the data to the buffer and return without
|
||||||
sending data.
|
sending data.
|
||||||
|
|
||||||
NOTES
|
@param net Network handler
|
||||||
The cached buffer can be sent as it is with 'net_flush()'.
|
@param packet Packet to send
|
||||||
|
@param len Length of packet
|
||||||
|
|
||||||
|
@note
|
||||||
|
The cached buffer can be sent as it is with 'net_flush()'.
|
||||||
In this code we have to be careful to not send a packet longer than
|
In this code we have to be careful to not send a packet longer than
|
||||||
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
|
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
|
||||||
protocol as we store the length of the compressed packet in 3 bytes.
|
protocol as we store the length of the compressed packet in 3 bytes.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
1
|
@retval
|
||||||
|
1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static my_bool
|
static my_bool
|
||||||
|
|
@ -547,9 +538,12 @@ net_write_buff(NET *net, const uchar *packet, ulong len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read and write one packet using timeouts.
|
Read and write one packet using timeouts.
|
||||||
If needed, the packet is compressed before sending.
|
If needed, the packet is compressed before sending.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
- TODO is it needed to set this variable if we have no socket
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -726,18 +720,17 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Help function to clear the commuication buffer when we get a too big packet.
|
Help function to clear the commuication buffer when we get a too big packet.
|
||||||
|
|
||||||
SYNOPSIS
|
@param net Communication handle
|
||||||
my_net_skip_rest()
|
@param remain Bytes to read
|
||||||
net Communication handle
|
@param alarmed Parameter for thr_alarm()
|
||||||
remain Bytes to read
|
@param alarm_buff Parameter for thr_alarm()
|
||||||
alarmed Parameter for thr_alarm()
|
|
||||||
alarm_buff Parameter for thr_alarm()
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 Was able to read the whole packet
|
0 Was able to read the whole packet
|
||||||
|
@retval
|
||||||
1 Got mailformed packet from client
|
1 Got mailformed packet from client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -780,10 +773,13 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
|
||||||
#endif /* NO_ALARM */
|
#endif /* NO_ALARM */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Reads one packet to net->buff + net->where_b
|
Reads one packet to net->buff + net->where_b.
|
||||||
Returns length of packet. Long packets are handled by my_net_read().
|
Long packets are handled by my_net_read().
|
||||||
This function reallocates the net->buff buffer if necessary.
|
This function reallocates the net->buff buffer if necessary.
|
||||||
|
|
||||||
|
@return
|
||||||
|
Returns length of packet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static ulong
|
static ulong
|
||||||
|
|
@ -972,15 +968,18 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read a packet from the client/server and return it without the internal
|
Read a packet from the client/server and return it without the internal
|
||||||
package header.
|
package header.
|
||||||
|
|
||||||
If the packet is the first packet of a multi-packet packet
|
If the packet is the first packet of a multi-packet packet
|
||||||
(which is indicated by the length of the packet = 0xffffff) then
|
(which is indicated by the length of the packet = 0xffffff) then
|
||||||
all sub packets are read and concatenated.
|
all sub packets are read and concatenated.
|
||||||
|
|
||||||
If the packet was compressed, its uncompressed and the length of the
|
If the packet was compressed, its uncompressed and the length of the
|
||||||
uncompressed packet is returned.
|
uncompressed packet is returned.
|
||||||
|
|
||||||
|
@return
|
||||||
The function returns the length of the found packet or packet_error.
|
The function returns the length of the found packet or packet_error.
|
||||||
net->read_pos points to the read data.
|
net->read_pos points to the read data.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Windows NT Service class library
|
@file
|
||||||
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
|
|
||||||
This file is public domain and comes with NO WARRANTY of any kind
|
@brief
|
||||||
-------------------------------------------------------------------------- */
|
Windows NT Service class library.
|
||||||
|
|
||||||
|
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
|
||||||
|
This file is public domain and comes with NO WARRANTY of any kind
|
||||||
|
*/
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -73,12 +77,13 @@ BOOL NTService::GetOS()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Init() Registers the main service thread with the service manager
|
Registers the main service thread with the service manager.
|
||||||
|
|
||||||
|
@param ServiceThread pointer to the main programs entry function
|
||||||
|
when the service is started
|
||||||
|
*/
|
||||||
|
|
||||||
ServiceThread - pointer to the main programs entry function
|
|
||||||
when the service is started
|
|
||||||
-------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
long NTService::Init(LPCSTR szInternName,void *ServiceThread)
|
long NTService::Init(LPCSTR szInternName,void *ServiceThread)
|
||||||
{
|
{
|
||||||
|
|
@ -99,13 +104,15 @@ long NTService::Init(LPCSTR szInternName,void *ServiceThread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Install() - Installs the service with Service manager
|
Installs the service with Service manager.
|
||||||
|
|
||||||
nError values:
|
nError values:
|
||||||
0 success
|
- 0 success
|
||||||
1 Can't open the Service manager
|
- 1 Can't open the Service manager
|
||||||
2 Failed to create service
|
- 2 Failed to create service.
|
||||||
-------------------------------------------------------------------------- */
|
*/
|
||||||
|
|
||||||
|
|
||||||
BOOL NTService::Install(int startType, LPCSTR szInternName,
|
BOOL NTService::Install(int startType, LPCSTR szInternName,
|
||||||
LPCSTR szDisplayName,
|
LPCSTR szDisplayName,
|
||||||
|
|
@ -155,14 +162,16 @@ BOOL NTService::Install(int startType, LPCSTR szInternName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Remove() - Removes the service
|
Removes the service.
|
||||||
|
|
||||||
nError values:
|
nError values:
|
||||||
0 success
|
- 0 success
|
||||||
1 Can't open the Service manager
|
- 1 Can't open the Service manager
|
||||||
2 Failed to locate service
|
- 2 Failed to locate service
|
||||||
3 Failed to delete service
|
- 3 Failed to delete service.
|
||||||
-------------------------------------------------------------------------- */
|
*/
|
||||||
|
|
||||||
|
|
||||||
BOOL NTService::Remove(LPCSTR szInternName)
|
BOOL NTService::Remove(LPCSTR szInternName)
|
||||||
{
|
{
|
||||||
|
|
@ -199,10 +208,10 @@ BOOL NTService::Remove(LPCSTR szInternName)
|
||||||
return ret_value;
|
return ret_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Stop() - this function should be called before the app. exits to stop
|
this function should be called before the app. exits to stop
|
||||||
the service
|
the service
|
||||||
-------------------------------------------------------------------------- */
|
*/
|
||||||
void NTService::Stop(void)
|
void NTService::Stop(void)
|
||||||
{
|
{
|
||||||
SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 60000);
|
SetStatus(SERVICE_STOP_PENDING,NO_ERROR, 0, 1, 60000);
|
||||||
|
|
@ -210,10 +219,11 @@ void NTService::Stop(void)
|
||||||
SetStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 1000);
|
SetStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
ServiceMain() - This is the function that is called from the
|
This is the function that is called from the
|
||||||
service manager to start the service
|
service manager to start the service.
|
||||||
-------------------------------------------------------------------------- */
|
*/
|
||||||
|
|
||||||
|
|
||||||
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
|
void NTService::ServiceMain(DWORD argc, LPTSTR *argv)
|
||||||
{
|
{
|
||||||
|
|
@ -264,9 +274,9 @@ error:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
StartService() - starts the appliaction thread
|
starts the appliaction thread.
|
||||||
-------------------------------------------------------------------------- */
|
*/
|
||||||
|
|
||||||
BOOL NTService::StartService()
|
BOOL NTService::StartService()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
/* ------------------------------------------------------------------------
|
/**
|
||||||
Windows NT Service class library
|
@file
|
||||||
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
|
|
||||||
This file is public domain and comes with NO WARRANTY of any kind
|
@brief
|
||||||
-------------------------------------------------------------------------- */
|
Windows NT Service class library
|
||||||
|
|
||||||
|
Copyright Abandoned 1998 Irena Pancirov - Irnet Snc
|
||||||
|
This file is public domain and comes with NO WARRANTY of any kind
|
||||||
|
*/
|
||||||
|
|
||||||
// main application thread
|
// main application thread
|
||||||
typedef void (*THREAD_FC)(void *);
|
typedef void (*THREAD_FC)(void *);
|
||||||
|
|
@ -13,7 +17,7 @@ class NTService
|
||||||
NTService();
|
NTService();
|
||||||
~NTService();
|
~NTService();
|
||||||
|
|
||||||
BOOL bOsNT; // true if OS is NT, false for Win95
|
BOOL bOsNT; ///< true if OS is NT, false for Win95
|
||||||
//install optinos
|
//install optinos
|
||||||
DWORD dwDesiredAccess;
|
DWORD dwDesiredAccess;
|
||||||
DWORD dwServiceType;
|
DWORD dwServiceType;
|
||||||
|
|
|
||||||
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
|
Optimising of MIN(), MAX() and COUNT(*) queries without 'group by' clause
|
||||||
by replacing the aggregate expression with a constant.
|
by replacing the aggregate expression with a constant.
|
||||||
|
|
||||||
|
|
@ -22,6 +24,7 @@
|
||||||
types of queries are optimised (assuming the table handler supports
|
types of queries are optimised (assuming the table handler supports
|
||||||
the required methods)
|
the required methods)
|
||||||
|
|
||||||
|
@verbatim
|
||||||
SELECT COUNT(*) FROM t1[,t2,t3,...]
|
SELECT COUNT(*) FROM t1[,t2,t3,...]
|
||||||
SELECT MIN(b) FROM t1 WHERE a=const
|
SELECT MIN(b) FROM t1 WHERE a=const
|
||||||
SELECT MAX(c) FROM t1 WHERE a=const AND b=const
|
SELECT MAX(c) FROM t1 WHERE a=const AND b=const
|
||||||
|
|
@ -29,6 +32,7 @@
|
||||||
SELECT MIN(b) FROM t1 WHERE a=const AND b>const
|
SELECT MIN(b) FROM t1 WHERE a=const AND b>const
|
||||||
SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
SELECT MIN(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
||||||
SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
SELECT MAX(b) FROM t1 WHERE a=const AND b BETWEEN const AND const
|
||||||
|
@endverbatim
|
||||||
|
|
||||||
Instead of '<' one can use '<=', '>', '>=' and '=' as well.
|
Instead of '<' one can use '<=', '>', '>=' and '=' as well.
|
||||||
Instead of 'a=const' the condition 'a IS NULL' can be used.
|
Instead of 'a=const' the condition 'a IS NULL' can be used.
|
||||||
|
|
@ -36,10 +40,11 @@
|
||||||
If all selected fields are replaced then we will also remove all
|
If all selected fields are replaced then we will also remove all
|
||||||
involved tables and return the answer without any join. Thus, the
|
involved tables and return the answer without any join. Thus, the
|
||||||
following query will be replaced with a row of two constants:
|
following query will be replaced with a row of two constants:
|
||||||
|
@verbatim
|
||||||
SELECT MAX(b), MIN(d) FROM t1,t2
|
SELECT MAX(b), MIN(d) FROM t1,t2
|
||||||
WHERE a=const AND b<const AND d>const
|
WHERE a=const AND b<const AND d>const
|
||||||
|
@endverbatim
|
||||||
(assuming a index for column d of table t2 is defined)
|
(assuming a index for column d of table t2 is defined)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
@ -83,25 +88,25 @@ static ulonglong get_exact_record_count(TABLE_LIST *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Substitutes constants for some COUNT(), MIN() and MAX() functions.
|
Substitutes constants for some COUNT(), MIN() and MAX() functions.
|
||||||
|
|
||||||
SYNOPSIS
|
@param tables list of leaves of join table tree
|
||||||
opt_sum_query()
|
@param all_fields All fields to be returned
|
||||||
tables list of leaves of join table tree
|
@param conds WHERE clause
|
||||||
all_fields All fields to be returned
|
|
||||||
conds WHERE clause
|
|
||||||
|
|
||||||
NOTE:
|
@note
|
||||||
This function is only called for queries with sum functions and no
|
This function is only called for queries with sum functions and no
|
||||||
GROUP BY part.
|
GROUP BY part.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 no errors
|
0 no errors
|
||||||
|
@retval
|
||||||
1 if all items were resolved
|
1 if all items were resolved
|
||||||
|
@retval
|
||||||
HA_ERR_KEY_NOT_FOUND on impossible conditions
|
HA_ERR_KEY_NOT_FOUND on impossible conditions
|
||||||
OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
|
@retval
|
||||||
wait timeout happens, for example
|
HA_ERR_... if a deadlock or a lock wait timeout happens, for example
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
||||||
|
|
@ -473,19 +478,18 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Test if the predicate compares a field with constants
|
Test if the predicate compares a field with constants.
|
||||||
|
|
||||||
SYNOPSIS
|
@param func_item Predicate item
|
||||||
simple_pred()
|
@param[out] args Here we store the field followed by constants
|
||||||
func_item Predicate item
|
@param[out] inv_order Is set to 1 if the predicate is of the form
|
||||||
args out: Here we store the field followed by constants
|
'const op field'
|
||||||
inv_order out: Is set to 1 if the predicate is of the form
|
|
||||||
'const op field'
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 func_item is a simple predicate: a field is compared with
|
0 func_item is a simple predicate: a field is compared with
|
||||||
constants
|
constants
|
||||||
|
@retval
|
||||||
1 Otherwise
|
1 Otherwise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -557,34 +561,33 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether a condition matches a key to get {MAX|MIN}(field):
|
Check whether a condition matches a key to get {MAX|MIN}(field):.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
matching_cond()
|
|
||||||
max_fl in: Set to 1 if we are optimising MAX()
|
|
||||||
ref in/out: Reference to the structure we store the key value
|
|
||||||
keyinfo in Reference to the key info
|
|
||||||
field_part in: Pointer to the key part for the field
|
|
||||||
cond in WHERE condition
|
|
||||||
key_part_used in/out: Map of matchings parts
|
|
||||||
range_fl in/out: Says whether including key will be used
|
|
||||||
prefix_len out: Length of common key part for the range
|
|
||||||
where MAX/MIN is searched for
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
For the index specified by the keyinfo parameter, index that
|
For the index specified by the keyinfo parameter, index that
|
||||||
contains field as its component (field_part), the function
|
contains field as its component (field_part), the function
|
||||||
checks whether the condition cond is a conjunction and all its
|
checks whether the condition cond is a conjunction and all its
|
||||||
conjuncts referring to the columns of the same table as column
|
conjuncts referring to the columns of the same table as column
|
||||||
field are one of the following forms:
|
field are one of the following forms:
|
||||||
- f_i= const_i or const_i= f_i or f_i is null,
|
- f_i= const_i or const_i= f_i or f_i is null,
|
||||||
where f_i is part of the index
|
where f_i is part of the index
|
||||||
- field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field
|
- field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field
|
||||||
- field between const1 and const2
|
- field between const1 and const2
|
||||||
|
|
||||||
RETURN
|
@param[in] max_fl Set to 1 if we are optimising MAX()
|
||||||
|
@param[in,out] ref Reference to the structure we store the key
|
||||||
|
value
|
||||||
|
@param[in] keyinfo Reference to the key info
|
||||||
|
@param[in] field_part Pointer to the key part for the field
|
||||||
|
@param[in] cond WHERE condition
|
||||||
|
@param[in,out] key_part_used Map of matchings parts
|
||||||
|
@param[in,out] range_fl Says whether including key will be used
|
||||||
|
@param[out] prefix_len Length of common key part for the range
|
||||||
|
where MAX/MIN is searched for
|
||||||
|
|
||||||
|
@retval
|
||||||
0 Index can't be used.
|
0 Index can't be used.
|
||||||
|
@retval
|
||||||
1 We can use index to get MIN/MAX value
|
1 We can use index to get MIN/MAX value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -749,31 +752,21 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether we can get value for {max|min}(field) by using a key.
|
Check whether we can get value for {max|min}(field) by using a key.
|
||||||
|
|
||||||
SYNOPSIS
|
If where-condition is not a conjunction of 0 or more conjuct the
|
||||||
find_key_for_maxmin()
|
function returns false, otherwise it checks whether there is an
|
||||||
max_fl in: 0 for MIN(field) / 1 for MAX(field)
|
index including field as its k-th component/part such that:
|
||||||
ref in/out Reference to the structure we store the key value
|
|
||||||
field in: Field used inside MIN() / MAX()
|
|
||||||
cond in: WHERE condition
|
|
||||||
range_fl out: Bit flags for how to search if key is ok
|
|
||||||
prefix_len out: Length of prefix for the search range
|
|
||||||
|
|
||||||
DESCRIPTION
|
-# for each previous component f_i there is one and only one conjunct
|
||||||
If where condition is not a conjunction of 0 or more conjuct the
|
|
||||||
function returns false, otherwise it checks whether there is an
|
|
||||||
index including field as its k-th component/part such that:
|
|
||||||
|
|
||||||
1. for each previous component f_i there is one and only one conjunct
|
|
||||||
of the form: f_i= const_i or const_i= f_i or f_i is null
|
of the form: f_i= const_i or const_i= f_i or f_i is null
|
||||||
2. references to field occur only in conjucts of the form:
|
-# references to field occur only in conjucts of the form:
|
||||||
field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
|
field {<|<=|>=|>|=} const or const {<|<=|>=|>|=} field or
|
||||||
field BETWEEN const1 AND const2
|
field BETWEEN const1 AND const2
|
||||||
3. all references to the columns from the same table as column field
|
-# all references to the columns from the same table as column field
|
||||||
occur only in conjucts mentioned above.
|
occur only in conjucts mentioned above.
|
||||||
4. each of k first components the index is not partial, i.e. is not
|
-# each of k first components the index is not partial, i.e. is not
|
||||||
defined on a fixed length proper prefix of the field.
|
defined on a fixed length proper prefix of the field.
|
||||||
|
|
||||||
If such an index exists the function through the ref parameter
|
If such an index exists the function through the ref parameter
|
||||||
|
|
@ -781,17 +774,26 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
|
||||||
the length of first (k-1) components of the key and flags saying
|
the length of first (k-1) components of the key and flags saying
|
||||||
how to apply the key for the search max/min value.
|
how to apply the key for the search max/min value.
|
||||||
(if we have a condition field = const, prefix_len contains the length
|
(if we have a condition field = const, prefix_len contains the length
|
||||||
of the whole search key)
|
of the whole search key)
|
||||||
|
|
||||||
NOTE
|
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
||||||
|
@param[in,out] ref Reference to the structure we store the key value
|
||||||
|
@param[in] field Field used inside MIN() / MAX()
|
||||||
|
@param[in] cond WHERE condition
|
||||||
|
@param[out] range_fl Bit flags for how to search if key is ok
|
||||||
|
@param[out] prefix_len Length of prefix for the search range
|
||||||
|
|
||||||
|
@note
|
||||||
This function may set table->key_read to 1, which must be reset after
|
This function may set table->key_read to 1, which must be reset after
|
||||||
index is used! (This can only happen when function returns 1)
|
index is used! (This can only happen when function returns 1)
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Index can not be used to optimize MIN(field)/MAX(field)
|
0 Index can not be used to optimize MIN(field)/MAX(field)
|
||||||
1 Can use key to optimize MIN()/MAX()
|
@retval
|
||||||
In this case ref, range_fl and prefix_len are updated
|
1 Can use key to optimize MIN()/MAX().
|
||||||
*/
|
In this case ref, range_fl and prefix_len are updated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
|
static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
|
||||||
Field* field, COND *cond,
|
Field* field, COND *cond,
|
||||||
|
|
@ -884,20 +886,19 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether found key is in range specified by conditions
|
Check whether found key is in range specified by conditions.
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
||||||
reckey_in_range()
|
@param[in] ref Reference to the key value and info
|
||||||
max_fl in: 0 for MIN(field) / 1 for MAX(field)
|
@param[in] field Field used the MIN/MAX expression
|
||||||
ref in: Reference to the key value and info
|
@param[in] cond WHERE condition
|
||||||
field in: Field used the MIN/MAX expression
|
@param[in] range_fl Says whether there is a condition to to be checked
|
||||||
cond in: WHERE condition
|
@param[in] prefix_len Length of the constant part of the key
|
||||||
range_fl in: Says whether there is a condition to to be checked
|
|
||||||
prefix_len in: Length of the constant part of the key
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 WHERE was not true for the found row
|
1 WHERE was not true for the found row
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -912,16 +913,16 @@ static int reckey_in_range(bool max_fl, TABLE_REF *ref, Field* field,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whether {MAX|MIN}(field) is in range specified by conditions
|
Check whether {MAX|MIN}(field) is in range specified by conditions.
|
||||||
SYNOPSIS
|
|
||||||
maxmin_in_range()
|
|
||||||
max_fl in: 0 for MIN(field) / 1 for MAX(field)
|
|
||||||
field in: Field used the MIN/MAX expression
|
|
||||||
cond in: WHERE condition
|
|
||||||
|
|
||||||
RETURN
|
@param[in] max_fl 0 for MIN(field) / 1 for MAX(field)
|
||||||
|
@param[in] field Field used the MIN/MAX expression
|
||||||
|
@param[in] cond WHERE condition
|
||||||
|
|
||||||
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 WHERE was not true for the found row
|
1 WHERE was not true for the found row
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,12 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
// Text .frm files management routines
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Text .frm files management routines
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
@ -22,17 +27,16 @@
|
||||||
#include <my_dir.h>
|
#include <my_dir.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
write string with escaping
|
Write string with escaping.
|
||||||
|
|
||||||
SYNOPSIS
|
@param file IO_CACHE for record
|
||||||
write_escaped_string()
|
@param val_s string for writing
|
||||||
file - IO_CACHE for record
|
|
||||||
val_s - string for writing
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE - OK
|
FALSE OK
|
||||||
TRUE - error
|
@retval
|
||||||
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static my_bool
|
static my_bool
|
||||||
|
|
@ -77,21 +81,21 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
write parameter value to IO_CACHE
|
Write parameter value to IO_CACHE.
|
||||||
|
|
||||||
SYNOPSIS
|
@param file pointer to IO_CACHE structure for writing
|
||||||
write_parameter()
|
@param base pointer to data structure
|
||||||
file pointer to IO_CACHE structure for writing
|
@param parameter pointer to parameter descriptor
|
||||||
base pointer to data structure
|
@param old_version for returning back old version number value
|
||||||
parameter pointer to parameter descriptor
|
|
||||||
old_version for returning back old version number value
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE - OK
|
FALSE OK
|
||||||
TRUE - error
|
@retval
|
||||||
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static my_bool
|
static my_bool
|
||||||
write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
|
write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
|
||||||
ulonglong *old_version)
|
ulonglong *old_version)
|
||||||
|
|
@ -191,24 +195,24 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
write new .frm
|
Write new .frm.
|
||||||
|
|
||||||
SYNOPSIS
|
@param dir directory where put .frm
|
||||||
sql_create_definition_file()
|
@param file_name .frm file name
|
||||||
dir directory where put .frm
|
@param type .frm type string (VIEW, TABLE)
|
||||||
file .frm file name
|
@param base base address for parameter reading (structure like
|
||||||
type .frm type string (VIEW, TABLE)
|
TABLE)
|
||||||
base base address for parameter reading (structure like
|
@param parameters parameters description
|
||||||
TABLE)
|
@param max_versions number of versions to save
|
||||||
parameters parameters description
|
|
||||||
max_versions number of versions to save
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE - OK
|
FALSE OK
|
||||||
TRUE - error
|
@retval
|
||||||
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
my_bool
|
my_bool
|
||||||
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
|
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
|
||||||
const LEX_STRING *type,
|
const LEX_STRING *type,
|
||||||
|
|
@ -345,21 +349,19 @@ err_w_file:
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Renames a frm file (including backups) in same schema
|
Renames a frm file (including backups) in same schema.
|
||||||
|
|
||||||
SYNOPSIS
|
@param schema name of given schema
|
||||||
rename_in_schema_file
|
@param old_name original file name
|
||||||
schema name of given schema
|
@param new_name new file name
|
||||||
old_name original file name
|
@param revision revision number
|
||||||
new_name new file name
|
@param num_view_backups number of backups
|
||||||
revision revision number
|
|
||||||
num_view_backups number of backups
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 - OK
|
|
||||||
1 - Error (only if renaming of frm failed)
|
|
||||||
|
|
||||||
|
@retval
|
||||||
|
0 OK
|
||||||
|
@retval
|
||||||
|
1 Error (only if renaming of frm failed)
|
||||||
*/
|
*/
|
||||||
my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
||||||
const char *new_name, ulonglong revision,
|
const char *new_name, ulonglong revision,
|
||||||
|
|
@ -401,21 +403,20 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare frm to parse (read to memory)
|
Prepare frm to parse (read to memory).
|
||||||
|
|
||||||
SYNOPSIS
|
@param file_name path & filename to .frm file
|
||||||
sql_parse_prepare()
|
@param mem_root MEM_ROOT for buffer allocation
|
||||||
file_name - path & filename to .frm file
|
@param bad_format_errors send errors on bad content
|
||||||
mem_root - MEM_ROOT for buffer allocation
|
|
||||||
bad_format_errors - send errors on bad content
|
|
||||||
|
|
||||||
RETURN
|
@note
|
||||||
0 - error
|
|
||||||
parser object
|
|
||||||
|
|
||||||
NOTE
|
|
||||||
returned pointer + 1 will be type of .frm
|
returned pointer + 1 will be type of .frm
|
||||||
|
|
||||||
|
@return
|
||||||
|
0 - error
|
||||||
|
@return
|
||||||
|
parser object
|
||||||
*/
|
*/
|
||||||
|
|
||||||
File_parser *
|
File_parser *
|
||||||
|
|
@ -506,22 +507,22 @@ frm_error:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
parse LEX_STRING
|
parse LEX_STRING.
|
||||||
|
|
||||||
SYNOPSIS
|
@param ptr pointer on string beginning
|
||||||
parse_string()
|
@param end pointer on symbol after parsed string end (still owned
|
||||||
ptr - pointer on string beginning
|
by buffer and can be accessed
|
||||||
end - pointer on symbol after parsed string end (still owned
|
@param mem_root MEM_ROOT for parameter allocation
|
||||||
by buffer and can be accessed
|
@param str pointer on string, where results should be stored
|
||||||
mem_root - MEM_ROOT for parameter allocation
|
|
||||||
str - pointer on string, where results should be stored
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - error
|
0 error
|
||||||
# - pointer on symbol after string
|
@retval
|
||||||
|
\# pointer on symbol after string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
||||||
{
|
{
|
||||||
|
|
@ -539,18 +540,17 @@ parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
read escaped string from ptr to eol in already allocated str
|
read escaped string from ptr to eol in already allocated str.
|
||||||
|
|
||||||
SYNOPSIS
|
@param ptr pointer on string beginning
|
||||||
read_escaped_string()
|
@param eol pointer on character after end of string
|
||||||
ptr - pointer on string beginning
|
@param str target string
|
||||||
eol - pointer on character after end of string
|
|
||||||
str - target string
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE - OK
|
FALSE OK
|
||||||
TRUE - error
|
@retval
|
||||||
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool
|
my_bool
|
||||||
|
|
@ -598,22 +598,22 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
parse \n delimited escaped string
|
parse \\n delimited escaped string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param ptr pointer on string beginning
|
||||||
parse_escaped_string()
|
@param end pointer on symbol after parsed string end (still owned
|
||||||
ptr - pointer on string beginning
|
by buffer and can be accessed
|
||||||
end - pointer on symbol after parsed string end (still owned
|
@param mem_root MEM_ROOT for parameter allocation
|
||||||
by buffer and can be accessed
|
@param str pointer on string, where results should be stored
|
||||||
mem_root - MEM_ROOT for parameter allocation
|
|
||||||
str - pointer on string, where results should be stored
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - error
|
0 error
|
||||||
# - pointer on symbol after string
|
@retval
|
||||||
|
\# pointer on symbol after string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
||||||
{
|
{
|
||||||
|
|
@ -628,20 +628,19 @@ parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
parse '' delimited escaped string
|
parse '' delimited escaped string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param ptr pointer on string beginning
|
||||||
parse_quoted_escaped_string()
|
@param end pointer on symbol after parsed string end (still owned
|
||||||
ptr - pointer on string beginning
|
by buffer and can be accessed
|
||||||
end - pointer on symbol after parsed string end (still owned
|
@param mem_root MEM_ROOT for parameter allocation
|
||||||
by buffer and can be accessed
|
@param str pointer on string, where results should be stored
|
||||||
mem_root - MEM_ROOT for parameter allocation
|
|
||||||
str - pointer on string, where results should be stored
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - error
|
0 error
|
||||||
# - pointer on symbol after string
|
@retval
|
||||||
|
\# pointer on symbol after string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
|
@ -673,18 +672,16 @@ parse_quoted_escaped_string(char *ptr, char *end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Parser for FILE_OPTIONS_ULLLIST type value.
|
Parser for FILE_OPTIONS_ULLLIST type value.
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in,out] ptr pointer to parameter
|
||||||
get_file_options_ulllist()
|
@param[in] end end of the configuration
|
||||||
ptr [in/out] pointer to parameter
|
@param[in] line pointer to the line begining
|
||||||
end [in] end of the configuration
|
@param[in] base base address for parameter writing (structure
|
||||||
line [in] pointer to the line begining
|
like TABLE)
|
||||||
base [in] base address for parameter writing (structure
|
@param[in] parameter description
|
||||||
like TABLE)
|
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||||
parameter [in] description
|
|
||||||
mem_root [in] MEM_ROOT for parameters allocation
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool get_file_options_ulllist(char *&ptr, char *end, char *line,
|
bool get_file_options_ulllist(char *&ptr, char *end, char *line,
|
||||||
|
|
@ -728,28 +725,28 @@ nlist_err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
parse parameters
|
parse parameters.
|
||||||
|
|
||||||
SYNOPSIS
|
@param base base address for parameter writing (structure like
|
||||||
File_parser::parse()
|
TABLE)
|
||||||
base base address for parameter writing (structure like
|
@param mem_root MEM_ROOT for parameters allocation
|
||||||
TABLE)
|
@param parameters parameters description
|
||||||
mem_root MEM_ROOT for parameters allocation
|
@param required number of required parameters in above list. If the file
|
||||||
parameters parameters description
|
contains more parameters than "required", they will
|
||||||
required number of parameters in the above list. If the file
|
be ignored. If the file contains less parameters
|
||||||
contains more parameters than "required", they will
|
then "required", non-existing parameters will
|
||||||
be ignored. If the file contains less parameters
|
remain their values.
|
||||||
then "required", non-existing parameters will
|
@param hook hook called for unknown keys
|
||||||
remain their values.
|
@param hook_data some data specific for the hook
|
||||||
hook hook called for unknown keys
|
|
||||||
hook_data some data specific for the hook
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE - OK
|
FALSE OK
|
||||||
TRUE - error
|
@retval
|
||||||
|
TRUE error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
my_bool
|
my_bool
|
||||||
File_parser::parse(uchar* base, MEM_ROOT *mem_root,
|
File_parser::parse(uchar* base, MEM_ROOT *mem_root,
|
||||||
struct File_option *parameters, uint required,
|
struct File_option *parameters, uint required,
|
||||||
|
|
@ -935,26 +932,25 @@ list_err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Dummy unknown key hook
|
Dummy unknown key hook.
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in,out] unknown_key reference on the line with unknown
|
||||||
File_parser_dummy_hook::process_unknown_string()
|
parameter and the parsing point
|
||||||
unknown_key [in/out] reference on the line with unknown
|
@param[in] base base address for parameter writing
|
||||||
parameter and the parsing point
|
(structure like TABLE)
|
||||||
base [in] base address for parameter writing (structure like
|
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||||
TABLE)
|
@param[in] end the end of the configuration
|
||||||
mem_root [in] MEM_ROOT for parameters allocation
|
|
||||||
end [in] the end of the configuration
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This hook used to catch no longer supported keys and process them for
|
This hook used to catch no longer supported keys and process them for
|
||||||
backward compatibility, but it will not slow down processing of modern
|
backward compatibility, but it will not slow down processing of modern
|
||||||
format files.
|
format files.
|
||||||
This hook does nothing except debug output.
|
This hook does nothing except debug output.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,27 +20,27 @@
|
||||||
#define PARSE_FILE_TIMESTAMPLENGTH 19
|
#define PARSE_FILE_TIMESTAMPLENGTH 19
|
||||||
|
|
||||||
enum file_opt_type {
|
enum file_opt_type {
|
||||||
FILE_OPTIONS_STRING, /* String (LEX_STRING) */
|
FILE_OPTIONS_STRING, /**< String (LEX_STRING) */
|
||||||
FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */
|
FILE_OPTIONS_ESTRING, /**< Escaped string (LEX_STRING) */
|
||||||
FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */
|
FILE_OPTIONS_ULONGLONG, /**< ulonglong parameter (ulonglong) */
|
||||||
FILE_OPTIONS_REV, /* Revision version number (ulonglong) */
|
FILE_OPTIONS_REV, /**< Revision version number (ulonglong) */
|
||||||
FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be
|
FILE_OPTIONS_TIMESTAMP, /**< timestamp (LEX_STRING have to be
|
||||||
allocated with length 20 (19+1) */
|
allocated with length 20 (19+1) */
|
||||||
FILE_OPTIONS_STRLIST, /* list of escaped strings
|
FILE_OPTIONS_STRLIST, /**< list of escaped strings
|
||||||
(List<LEX_STRING>) */
|
(List<LEX_STRING>) */
|
||||||
FILE_OPTIONS_ULLLIST /* list of ulonglong values
|
FILE_OPTIONS_ULLLIST /**< list of ulonglong values
|
||||||
(List<ulonglong>) */
|
(List<ulonglong>) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct File_option
|
struct File_option
|
||||||
{
|
{
|
||||||
LEX_STRING name; /* Name of the option */
|
LEX_STRING name; /**< Name of the option */
|
||||||
int offset; /* offset to base address of value */
|
int offset; /**< offset to base address of value */
|
||||||
file_opt_type type; /* Option type */
|
file_opt_type type; /**< Option type */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This hook used to catch no longer supported keys and process them for
|
This hook used to catch no longer supported keys and process them for
|
||||||
backward compatibility.
|
backward compatibility.
|
||||||
*/
|
*/
|
||||||
|
|
@ -55,7 +55,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Dummy hook for parsers which do not need hook for unknown keys */
|
/** Dummy hook for parsers which do not need hook for unknown keys. */
|
||||||
|
|
||||||
class File_parser_dummy_hook: public Unknown_key_hook
|
class File_parser_dummy_hook: public Unknown_key_hook
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -68,10 +68,13 @@ my_decimal *Item_proc_real::val_decimal(my_decimal *decimal_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/**
|
||||||
** Setup handling of procedure
|
Setup handling of procedure.
|
||||||
** Return 0 if everything is ok
|
|
||||||
*****************************************************************************/
|
@return
|
||||||
|
Return 0 if everything is ok
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
Procedure *
|
Procedure *
|
||||||
setup_procedure(THD *thd,ORDER *param,select_result *result,
|
setup_procedure(THD *thd,ORDER *param,select_result *result,
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PROC_NO_SORT 1 /* Bits in flags */
|
#define PROC_NO_SORT 1 /**< Bits in flags */
|
||||||
#define PROC_GROUP 2 /* proc must have group */
|
#define PROC_GROUP 2 /**< proc must have group */
|
||||||
|
|
||||||
/* Procedure items used by procedures to store values for send_fields */
|
/* Procedure items used by procedures to store values for send_fields */
|
||||||
|
|
||||||
|
|
|
||||||
188
sql/protocol.cc
188
sql/protocol.cc
|
|
@ -13,8 +13,10 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Low level functions for storing data to be send to the MySQL client
|
@file
|
||||||
|
|
||||||
|
Low level functions for storing data to be send to the MySQL client.
|
||||||
The actual communction is handled by the net_xxx functions in net_serv.cc
|
The actual communction is handled by the net_xxx functions in net_serv.cc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -53,17 +55,18 @@ bool Protocol_binary::net_store_data(const uchar *from, size_t length)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Send a error string to client
|
Send a error string to client.
|
||||||
|
|
||||||
Design note:
|
Design note:
|
||||||
|
|
||||||
net_send_error is a low-level functions
|
net_printf_error and net_send_error are low-level functions
|
||||||
that shall be used only when a new connection is being
|
that shall be used only when a new connection is being
|
||||||
established or at server startup.
|
established or at server startup.
|
||||||
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
|
|
||||||
critical that every error that can be intercepted is issued in one
|
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
|
||||||
place only, my_message_sql.
|
critical that every error that can be intercepted is issued in one
|
||||||
|
place only, my_message_sql.
|
||||||
*/
|
*/
|
||||||
void net_send_error(THD *thd, uint sql_errno, const char *err)
|
void net_send_error(THD *thd, uint sql_errno, const char *err)
|
||||||
{
|
{
|
||||||
|
|
@ -126,32 +129,28 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*
|
|
||||||
Return ok to the client.
|
Return ok to the client.
|
||||||
|
|
||||||
SYNOPSIS
|
The ok packet has the following structure:
|
||||||
send_ok()
|
|
||||||
thd Thread handler
|
|
||||||
affected_rows Number of rows changed by statement
|
|
||||||
id Auto_increment id for first row (if used)
|
|
||||||
message Message to send to the client (Used by mysql_status)
|
|
||||||
|
|
||||||
DESCRIPTION
|
- 0 : Marker (1 byte)
|
||||||
The ok packet has the following structure
|
- affected_rows : Stored in 1-9 bytes
|
||||||
|
- id : Stored in 1-9 bytes
|
||||||
|
- server_status : Copy of thd->server_status; Can be used by client
|
||||||
|
to check if we are inside an transaction.
|
||||||
|
New in 4.0 protocol
|
||||||
|
- warning_count : Stored in 2 bytes; New in 4.1 protocol
|
||||||
|
- message : Stored as packed length (1-9 bytes) + message.
|
||||||
|
Is not stored if no message.
|
||||||
|
|
||||||
0 Marker (1 byte)
|
If net->no_send_ok return without sending packet.
|
||||||
affected_rows Stored in 1-9 bytes
|
|
||||||
id Stored in 1-9 bytes
|
|
||||||
server_status Copy of thd->server_status; Can be used by client
|
|
||||||
to check if we are inside an transaction
|
|
||||||
New in 4.0 protocol
|
|
||||||
warning_count Stored in 2 bytes; New in 4.1 protocol
|
|
||||||
message Stored as packed length (1-9 bytes) + message
|
|
||||||
Is not stored if no message
|
|
||||||
|
|
||||||
If net->no_send_ok return without sending packet
|
@param thd Thread handler
|
||||||
*/
|
@param affected_rows Number of rows changed by statement
|
||||||
|
@param id Auto_increment id for first row (if used)
|
||||||
|
@param message Message to send to the client (Used by mysql_status)
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
void
|
void
|
||||||
|
|
@ -207,27 +206,24 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
|
||||||
|
|
||||||
static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
|
static uchar eof_buff[1]= { (uchar) 254 }; /* Marker for end of fields */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Send eof (= end of result set) to the client
|
Send eof (= end of result set) to the client.
|
||||||
|
|
||||||
SYNOPSIS
|
The eof packet has the following structure:
|
||||||
send_eof()
|
|
||||||
thd Thread handler
|
|
||||||
no_flush Set to 1 if there will be more data to the client,
|
|
||||||
like in send_fields().
|
|
||||||
|
|
||||||
DESCRIPTION
|
- 254 : Marker (1 byte)
|
||||||
The eof packet has the following structure
|
- warning_count : Stored in 2 bytes; New in 4.1 protocol
|
||||||
|
- status_flag : Stored in 2 bytes;
|
||||||
|
For flags like SERVER_MORE_RESULTS_EXISTS.
|
||||||
|
|
||||||
254 Marker (1 byte)
|
Note that the warning count will not be sent if 'no_flush' is set as
|
||||||
warning_count Stored in 2 bytes; New in 4.1 protocol
|
we don't want to report the warning count until all data is sent to the
|
||||||
status_flag Stored in 2 bytes;
|
client.
|
||||||
For flags like SERVER_MORE_RESULTS_EXISTS
|
|
||||||
|
|
||||||
Note that the warning count will not be sent if 'no_flush' is set as
|
@param thd Thread handler
|
||||||
we don't want to report the warning count until all data is sent to the
|
@param no_flush Set to 1 if there will be more data to the client,
|
||||||
client.
|
like in send_fields().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
send_eof(THD *thd)
|
send_eof(THD *thd)
|
||||||
|
|
@ -245,7 +241,7 @@ send_eof(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Format EOF packet according to the current protocol and
|
Format EOF packet according to the current protocol and
|
||||||
write it to the network output buffer.
|
write it to the network output buffer.
|
||||||
*/
|
*/
|
||||||
|
|
@ -276,15 +272,15 @@ static void write_eof_packet(THD *thd, NET *net)
|
||||||
VOID(my_net_write(net, eof_buff, 1));
|
VOID(my_net_write(net, eof_buff, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Please client to send scrambled_password in old format.
|
Please client to send scrambled_password in old format.
|
||||||
SYNOPSYS
|
|
||||||
send_old_password_request()
|
@param thd thread handle
|
||||||
thd thread handle
|
|
||||||
|
@retval
|
||||||
RETURN VALUE
|
0 ok
|
||||||
0 ok
|
@retval
|
||||||
!0 error
|
!0 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool send_old_password_request(THD *thd)
|
bool send_old_password_request(THD *thd)
|
||||||
|
|
@ -338,14 +334,15 @@ void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
|
||||||
|
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Faster net_store_length when we know that length is less than 65536.
|
Faster net_store_length when we know that length is less than 65536.
|
||||||
We keep a separate version for that range because it's widely used in
|
We keep a separate version for that range because it's widely used in
|
||||||
libmysql.
|
libmysql.
|
||||||
|
|
||||||
uint is used as agrument type because of MySQL type conventions:
|
uint is used as agrument type because of MySQL type conventions:
|
||||||
uint for 0..65536
|
- uint for 0..65536
|
||||||
ulong for 0..4294967296
|
- ulong for 0..4294967296
|
||||||
ulonglong for bigger numbers.
|
- ulonglong for bigger numbers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uchar *net_store_length_fast(uchar *packet, uint length)
|
static uchar *net_store_length_fast(uchar *packet, uint length)
|
||||||
|
|
@ -418,27 +415,26 @@ bool Protocol::flush()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
|
/**
|
||||||
Send name and type of result to client.
|
Send name and type of result to client.
|
||||||
|
|
||||||
SYNOPSIS
|
Sum fields has table name empty and field_name.
|
||||||
send_fields()
|
|
||||||
THD Thread data object
|
|
||||||
list List of items to send to client
|
|
||||||
flag Bit mask with the following functions:
|
|
||||||
1 send number of rows
|
|
||||||
2 send default values
|
|
||||||
4 don't write eof packet
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param THD Thread data object
|
||||||
Sum fields has table name empty and field_name.
|
@param list List of items to send to client
|
||||||
|
@param flag Bit mask with the following functions:
|
||||||
|
- 1 send number of rows
|
||||||
|
- 2 send default values
|
||||||
|
- 4 don't write eof packet
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
1 Error (Note that in this case the error is not sent to the client)
|
@retval
|
||||||
|
1 Error (Note that in this case the error is not sent to the
|
||||||
|
client)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
|
||||||
bool Protocol::send_fields(List<Item> *list, uint flags)
|
bool Protocol::send_fields(List<Item> *list, uint flags)
|
||||||
{
|
{
|
||||||
List_iterator_fast<Item> it(*list);
|
List_iterator_fast<Item> it(*list);
|
||||||
|
|
@ -592,18 +588,17 @@ bool Protocol::write()
|
||||||
#endif /* EMBEDDED_LIBRARY */
|
#endif /* EMBEDDED_LIBRARY */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Send \0 end terminated string
|
Send \\0 end terminated string.
|
||||||
|
|
||||||
SYNOPSIS
|
@param from NullS or \\0 terminated string
|
||||||
store()
|
|
||||||
from NullS or \0 terminated string
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
In most cases one should use store(from, length) instead of this function
|
In most cases one should use store(from, length) instead of this function
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -616,8 +611,8 @@ bool Protocol::store(const char *from, CHARSET_INFO *cs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Send a set of strings as one long string with ',' in between
|
Send a set of strings as one long string with ',' in between.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Protocol::store(I_List<i_string>* str_list)
|
bool Protocol::store(I_List<i_string>* str_list)
|
||||||
|
|
@ -669,7 +664,7 @@ bool Protocol_text::store_null()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Auxilary function to convert string to the given character set
|
Auxilary function to convert string to the given character set
|
||||||
and store in network buffer.
|
and store in network buffer.
|
||||||
*/
|
*/
|
||||||
|
|
@ -846,13 +841,12 @@ bool Protocol_text::store(Field *field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO:
|
@todo
|
||||||
Second_part format ("%06") needs to change when
|
Second_part format ("%06") needs to change when
|
||||||
we support 0-6 decimals for time.
|
we support 0-6 decimals for time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
bool Protocol_text::store(MYSQL_TIME *tm)
|
bool Protocol_text::store(MYSQL_TIME *tm)
|
||||||
{
|
{
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
|
|
@ -890,10 +884,10 @@ bool Protocol_text::store_date(MYSQL_TIME *tm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
TODO:
|
@todo
|
||||||
Second_part format ("%06") needs to change when
|
Second_part format ("%06") needs to change when
|
||||||
we support 0-6 decimals for time.
|
we support 0-6 decimals for time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Protocol_text::store_time(MYSQL_TIME *tm)
|
bool Protocol_text::store_time(MYSQL_TIME *tm)
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Class used for the old (MySQL 4.0 protocol) */
|
/** Class used for the old (MySQL 4.0 protocol). */
|
||||||
|
|
||||||
class Protocol_text :public Protocol
|
class Protocol_text :public Protocol
|
||||||
{
|
{
|
||||||
|
|
|
||||||
127
sql/records.cc
127
sql/records.cc
|
|
@ -14,7 +14,12 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* Functions for easy reading of records, possible through a cache */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
Functions for easy reading of records, possible through a cache
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
|
|
@ -31,25 +36,20 @@ static int rr_index_first(READ_RECORD *info);
|
||||||
static int rr_index(READ_RECORD *info);
|
static int rr_index(READ_RECORD *info);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Initialize READ_RECORD structure to perform full index scan
|
Initialize READ_RECORD structure to perform full index scan (in forward
|
||||||
|
direction) using read_record.read_record() interface.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
init_read_record_idx()
|
|
||||||
info READ_RECORD structure to initialize.
|
|
||||||
thd Thread handle
|
|
||||||
table Table to be accessed
|
|
||||||
print_error If true, call table->file->print_error() if an error
|
|
||||||
occurs (except for end-of-records error)
|
|
||||||
idx index to scan
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Initialize READ_RECORD structure to perform full index scan (in forward
|
|
||||||
direction) using read_record.read_record() interface.
|
|
||||||
|
|
||||||
This function has been added at late stage and is used only by
|
This function has been added at late stage and is used only by
|
||||||
UPDATE/DELETE. Other statements perform index scans using
|
UPDATE/DELETE. Other statements perform index scans using
|
||||||
join_read_first/next functions.
|
join_read_first/next functions.
|
||||||
|
|
||||||
|
@param info READ_RECORD structure to initialize.
|
||||||
|
@param thd Thread handle
|
||||||
|
@param table Table to be accessed
|
||||||
|
@param print_error If true, call table->file->print_error() if an error
|
||||||
|
occurs (except for end-of-records error)
|
||||||
|
@param idx index to scan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||||
|
|
@ -286,7 +286,7 @@ static int rr_handle_error(READ_RECORD *info, int error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Read a record from head-database */
|
/** Read a record from head-database. */
|
||||||
|
|
||||||
static int rr_quick(READ_RECORD *info)
|
static int rr_quick(READ_RECORD *info)
|
||||||
{
|
{
|
||||||
|
|
@ -308,20 +308,19 @@ static int rr_quick(READ_RECORD *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Reads first row in an index scan
|
Reads first row in an index scan.
|
||||||
|
|
||||||
SYNOPSIS
|
@param info Scan info
|
||||||
rr_index_first()
|
|
||||||
info Scan info
|
@retval
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 Ok
|
0 Ok
|
||||||
-1 End of records
|
@retval
|
||||||
1 Error
|
-1 End of records
|
||||||
|
@retval
|
||||||
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static int rr_index_first(READ_RECORD *info)
|
static int rr_index_first(READ_RECORD *info)
|
||||||
{
|
{
|
||||||
int tmp= info->file->index_first(info->record);
|
int tmp= info->file->index_first(info->record);
|
||||||
|
|
@ -332,24 +331,22 @@ static int rr_index_first(READ_RECORD *info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Reads index sequentially after first row
|
Reads index sequentially after first row.
|
||||||
|
|
||||||
SYNOPSIS
|
Read the next index record (in forward direction) and translate return
|
||||||
rr_index()
|
value.
|
||||||
info Scan info
|
|
||||||
|
@param info Scan info
|
||||||
DESCRIPTION
|
|
||||||
Read the next index record (in forward direction) and translate return
|
@retval
|
||||||
value.
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
0 Ok
|
0 Ok
|
||||||
-1 End of records
|
@retval
|
||||||
1 Error
|
-1 End of records
|
||||||
|
@retval
|
||||||
|
1 Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static int rr_index(READ_RECORD *info)
|
static int rr_index(READ_RECORD *info)
|
||||||
{
|
{
|
||||||
int tmp= info->file->index_next(info->record);
|
int tmp= info->file->index_next(info->record);
|
||||||
|
|
@ -403,22 +400,20 @@ static int rr_from_tempfile(READ_RECORD *info)
|
||||||
} /* rr_from_tempfile */
|
} /* rr_from_tempfile */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read a result set record from a temporary file after sorting
|
Read a result set record from a temporary file after sorting.
|
||||||
|
|
||||||
SYNOPSIS
|
The function first reads the next sorted record from the temporary file.
|
||||||
rr_unpack_from_tempfile()
|
into a buffer. If a success it calls a callback function that unpacks
|
||||||
info Reference to the context including record descriptors
|
the fields values use in the result set from this buffer into their
|
||||||
|
positions in the regular record buffer.
|
||||||
|
|
||||||
DESCRIPTION
|
@param info Reference to the context including record descriptors
|
||||||
The function first reads the next sorted record from the temporary file.
|
|
||||||
into a buffer. If a success it calls a callback function that unpacks
|
|
||||||
the fields values use in the result set from this buffer into their
|
|
||||||
positions in the regular record buffer.
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - Record successfully read.
|
0 Record successfully read.
|
||||||
-1 - There is no record to be read anymore.
|
@retval
|
||||||
|
-1 There is no record to be read anymore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int rr_unpack_from_tempfile(READ_RECORD *info)
|
static int rr_unpack_from_tempfile(READ_RECORD *info)
|
||||||
|
|
@ -456,22 +451,20 @@ static int rr_from_pointers(READ_RECORD *info)
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Read a result set record from a buffer after sorting
|
Read a result set record from a buffer after sorting.
|
||||||
|
|
||||||
SYNOPSIS
|
The function first reads the next sorted record from the sort buffer.
|
||||||
rr_unpack_from_buffer()
|
If a success it calls a callback function that unpacks
|
||||||
info Reference to the context including record descriptors
|
the fields values use in the result set from this buffer into their
|
||||||
|
positions in the regular record buffer.
|
||||||
|
|
||||||
DESCRIPTION
|
@param info Reference to the context including record descriptors
|
||||||
The function first reads the next sorted record from the sort buffer.
|
|
||||||
If a success it calls a callback function that unpacks
|
|
||||||
the fields values use in the result set from this buffer into their
|
|
||||||
positions in the regular record buffer.
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 - Record successfully read.
|
0 Record successfully read.
|
||||||
-1 - There is no record to be read anymore.
|
@retval
|
||||||
|
-1 There is no record to be read anymore.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int rr_unpack_from_buffer(READ_RECORD *info)
|
static int rr_unpack_from_buffer(READ_RECORD *info)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,16 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
All of the functions defined in this file which are not used (the ones to
|
||||||
|
handle failsafe) are not used; their code has not been updated for more
|
||||||
|
than one year now so should be considered as BADLY BROKEN. Do not enable
|
||||||
|
it. The used functions (to handle LOAD DATA FROM MASTER, plus some small
|
||||||
|
functions like register_slave()) are working.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
|
|
||||||
|
|
@ -144,12 +154,13 @@ void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Register slave in 'slave_list' hash table
|
Register slave in 'slave_list' hash table.
|
||||||
|
|
||||||
RETURN VALUES
|
@return
|
||||||
0 ok
|
0 ok
|
||||||
1 Error. Error message sent to client
|
@return
|
||||||
|
1 Error. Error message sent to client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int register_slave(THD* thd, uchar* packet, uint packet_length)
|
int register_slave(THD* thd, uchar* packet, uint packet_length)
|
||||||
|
|
@ -252,7 +263,8 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg)
|
||||||
/* Impossible */
|
/* Impossible */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@details
|
||||||
Before 4.0.15 we had a member of THD called log_pos, it was meant for
|
Before 4.0.15 we had a member of THD called log_pos, it was meant for
|
||||||
failsafe replication code in repl_failsafe.cc which is disabled until
|
failsafe replication code in repl_failsafe.cc which is disabled until
|
||||||
it is reworked. Event's log_pos used to be preserved through
|
it is reworked. Event's log_pos used to be preserved through
|
||||||
|
|
@ -388,8 +400,8 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Caller must delete result when done
|
Caller must delete result when done.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static Slave_log_event* find_slave_event(IO_CACHE* log,
|
static Slave_log_event* find_slave_event(IO_CACHE* log,
|
||||||
|
|
@ -428,9 +440,11 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
|
||||||
return (Slave_log_event*)ev;
|
return (Slave_log_event*)ev;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This function is broken now. See comment for translate_master().
|
This function is broken now.
|
||||||
*/
|
|
||||||
|
@seealso translate_master()
|
||||||
|
*/
|
||||||
|
|
||||||
bool show_new_master(THD* thd)
|
bool show_new_master(THD* thd)
|
||||||
{
|
{
|
||||||
|
|
@ -466,20 +480,19 @@ bool show_new_master(THD* thd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Asks the master for the list of its other connected slaves.
|
Asks the master for the list of its other connected slaves.
|
||||||
This is for failsafe replication:
|
|
||||||
|
This is for failsafe replication:
|
||||||
in order for failsafe replication to work, the servers involved in
|
in order for failsafe replication to work, the servers involved in
|
||||||
replication must know of each other. We accomplish this by having each
|
replication must know of each other. We accomplish this by having each
|
||||||
slave report to the master how to reach it, and on connection, each
|
slave report to the master how to reach it, and on connection, each
|
||||||
slave receives information about where the other slaves are.
|
slave receives information about where the other slaves are.
|
||||||
|
|
||||||
SYNOPSIS
|
@param mysql pre-existing connection to the master
|
||||||
update_slave_list()
|
@param mi master info
|
||||||
mysql pre-existing connection to the master
|
|
||||||
mi master info
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
mi is used only to give detailed error messages which include the
|
mi is used only to give detailed error messages which include the
|
||||||
hostname/port of the master, the username used by the slave to connect to
|
hostname/port of the master, the username used by the slave to connect to
|
||||||
the master.
|
the master.
|
||||||
|
|
@ -487,10 +500,11 @@ bool show_new_master(THD* thd)
|
||||||
REPLICATION SLAVE privilege, it will pop in this function because
|
REPLICATION SLAVE privilege, it will pop in this function because
|
||||||
SHOW SLAVE HOSTS will fail on the master.
|
SHOW SLAVE HOSTS will fail on the master.
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
1 error
|
1 error
|
||||||
|
@retval
|
||||||
0 success
|
0 success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int update_slave_list(MYSQL* mysql, Master_info* mi)
|
int update_slave_list(MYSQL* mysql, Master_info* mi)
|
||||||
{
|
{
|
||||||
|
|
@ -754,11 +768,16 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Load all MyISAM tables from master to this slave.
|
Load all MyISAM tables from master to this slave.
|
||||||
|
|
||||||
REQUIREMENTS
|
REQUIREMENTS
|
||||||
- No active transaction (flush_relay_log_info would not work in this case)
|
- No active transaction (flush_relay_log_info would not work in this case).
|
||||||
|
|
||||||
|
@todo
|
||||||
|
- add special option, not enabled
|
||||||
|
by default, to allow inclusion of mysql database into load
|
||||||
|
data from master
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool load_master_data(THD* thd)
|
bool load_master_data(THD* thd)
|
||||||
|
|
|
||||||
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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
Handling of MySQL SQL variables
|
Handling of MySQL SQL variables
|
||||||
|
|
||||||
|
@details
|
||||||
To add a new variable, one has to do the following:
|
To add a new variable, one has to do the following:
|
||||||
|
|
||||||
- Use one of the 'sys_var... classes from set_var.h or write a specific
|
- Use one of the 'sys_var... classes from set_var.h or write a specific
|
||||||
|
|
@ -28,18 +32,19 @@
|
||||||
- Don't forget to initialize new fields in global_system_variables and
|
- Don't forget to initialize new fields in global_system_variables and
|
||||||
max_system_variables!
|
max_system_variables!
|
||||||
|
|
||||||
NOTES:
|
@todo
|
||||||
- Be careful with var->save_result: sys_var::check() only updates
|
Add full support for the variable character_set (for 4.1)
|
||||||
|
|
||||||
|
@todo
|
||||||
|
When updating myisam_delay_key_write, we should do a 'flush tables'
|
||||||
|
of all MyISAM tables to ensure that they are reopen with the
|
||||||
|
new attribute.
|
||||||
|
|
||||||
|
@note
|
||||||
|
Be careful with var->save_result: sys_var::check() only updates
|
||||||
ulonglong_value; so other members of the union are garbage then; to use
|
ulonglong_value; so other members of the union are garbage then; to use
|
||||||
them you must first assign a value to them (in specific ::check() for
|
them you must first assign a value to them (in specific ::check() for
|
||||||
example).
|
example).
|
||||||
|
|
||||||
TODO:
|
|
||||||
- Add full support for the variable character_set (for 4.1)
|
|
||||||
|
|
||||||
- When updating myisam_delay_key_write, we should do a 'flush tables'
|
|
||||||
of all MyISAM tables to ensure that they are reopen with the
|
|
||||||
new attribute.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_IMPLEMENTATION
|
#ifdef USE_PRAGMA_IMPLEMENTATION
|
||||||
|
|
@ -824,9 +829,9 @@ static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
If one sets the LOW_PRIORIY UPDATES flag, we also must change the
|
If one sets the LOW_PRIORIY UPDATES flag, we also must change the
|
||||||
used lock type
|
used lock type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void fix_low_priority_updates(THD *thd, enum_var_type type)
|
static void fix_low_priority_updates(THD *thd, enum_var_type type)
|
||||||
|
|
@ -848,8 +853,8 @@ fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
|
||||||
(my_off_t) global_system_variables.myisam_max_sort_file_size;
|
(my_off_t) global_system_variables.myisam_max_sort_file_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR
|
Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void fix_max_join_size(THD *thd, enum_var_type type)
|
static void fix_max_join_size(THD *thd, enum_var_type type)
|
||||||
|
|
@ -864,7 +869,7 @@ static void fix_max_join_size(THD *thd, enum_var_type type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Can't change the 'next' tx_isolation while we are already in
|
Can't change the 'next' tx_isolation while we are already in
|
||||||
a transaction
|
a transaction
|
||||||
*/
|
*/
|
||||||
|
|
@ -880,7 +885,7 @@ static int check_tx_isolation(THD *thd, set_var *var)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If one doesn't use the SESSION modifier, the isolation level
|
If one doesn't use the SESSION modifier, the isolation level
|
||||||
is only active for the next command
|
is only active for the next command.
|
||||||
*/
|
*/
|
||||||
static void fix_tx_isolation(THD *thd, enum_var_type type)
|
static void fix_tx_isolation(THD *thd, enum_var_type type)
|
||||||
{
|
{
|
||||||
|
|
@ -1452,9 +1457,12 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return an Item for a variable. Used with @@[global.]variable_name
|
Return an Item for a variable.
|
||||||
If type is not given, return local value if exists, else global
|
|
||||||
|
Used with @@[global.]variable_name.
|
||||||
|
|
||||||
|
If type is not given, return local value if exists, else global.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
|
Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
|
||||||
|
|
@ -1616,7 +1624,7 @@ uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Update a date_time format variable based on given value */
|
/** Update a date_time format variable based on given value. */
|
||||||
|
|
||||||
void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
|
void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
|
||||||
DATE_TIME_FORMAT *new_value)
|
DATE_TIME_FORMAT *new_value)
|
||||||
|
|
@ -2048,6 +2056,12 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Abort if some other thread is changing the key cache.
|
||||||
|
This should be changed so that we wait until the previous
|
||||||
|
assignment is done and then do the new assign
|
||||||
|
*/
|
||||||
bool sys_var_key_cache_long::update(THD *thd, set_var *var)
|
bool sys_var_key_cache_long::update(THD *thd, set_var *var)
|
||||||
{
|
{
|
||||||
ulong tmp= (ulong) var->value->val_int();
|
ulong tmp= (ulong) var->value->val_int();
|
||||||
|
|
@ -2758,23 +2772,20 @@ static uchar *get_error_count(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Get the tmpdir that was specified or chosen by default
|
Get the tmpdir that was specified or chosen by default.
|
||||||
|
|
||||||
SYNOPSIS
|
This is necessary because if the user does not specify a temporary
|
||||||
get_tmpdir()
|
directory via the command line, one is chosen based on the environment
|
||||||
thd thread handle
|
or system defaults. But we can't just always use mysql_tmpdir, because
|
||||||
|
that is actually a call to my_tmpdir() which cycles among possible
|
||||||
|
temporary directories.
|
||||||
|
|
||||||
DESCRIPTION
|
@param thd thread handle
|
||||||
This is necessary because if the user does not specify a temporary
|
|
||||||
directory via the command line, one is chosen based on the environment
|
|
||||||
or system defaults. But we can't just always use mysql_tmpdir, because
|
|
||||||
that is actually a call to my_tmpdir() which cycles among possible
|
|
||||||
temporary directories.
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
ptr pointer to NUL-terminated string
|
ptr pointer to NUL-terminated string
|
||||||
*/
|
*/
|
||||||
static uchar *get_tmpdir(THD *thd)
|
static uchar *get_tmpdir(THD *thd)
|
||||||
{
|
{
|
||||||
if (opt_mysql_tmpdir)
|
if (opt_mysql_tmpdir)
|
||||||
|
|
@ -2789,16 +2800,16 @@ static uchar *get_tmpdir(THD *thd)
|
||||||
- Update loop
|
- Update loop
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find variable name in option my_getopt structure used for command line args
|
Find variable name in option my_getopt structure used for
|
||||||
|
command line args.
|
||||||
|
|
||||||
SYNOPSIS
|
@param opt option structure array to search in
|
||||||
find_option()
|
@param name variable name
|
||||||
opt option structure array to search in
|
|
||||||
name variable name
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
0 Error
|
0 Error
|
||||||
|
@retval
|
||||||
ptr pointer to option structure
|
ptr pointer to option structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2821,8 +2832,8 @@ static struct my_option *find_option(struct my_option *opt, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Return variable name and length for hashing of variables
|
Return variable name and length for hashing of variables.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static uchar *get_sys_var_length(const sys_var *var, size_t *length,
|
static uchar *get_sys_var_length(const sys_var *var, size_t *length,
|
||||||
|
|
@ -3025,17 +3036,17 @@ int mysql_append_static_vars(const SHOW_VAR *show_vars, uint count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find a user set-table variable
|
Find a user set-table variable.
|
||||||
|
|
||||||
SYNOPSIS
|
@param str Name of system variable to find
|
||||||
intern_find_sys_var()
|
@param length Length of variable. zero means that we should use strlen()
|
||||||
str Name of system variable to find
|
on the variable
|
||||||
length Length of variable. zero means that we should use strlen()
|
@param no_error Refuse to emit an error, even if one occurred.
|
||||||
on the variable
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
pointer pointer to variable definitions
|
pointer pointer to variable definitions
|
||||||
|
@retval
|
||||||
0 Unknown variable (error message is given)
|
0 Unknown variable (error message is given)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3056,25 +3067,23 @@ sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute update of all variables
|
Execute update of all variables.
|
||||||
|
|
||||||
SYNOPSIS
|
First run a check of all variables that all updates will go ok.
|
||||||
|
If yes, then execute all updates, returning an error if any one failed.
|
||||||
|
|
||||||
sql_set
|
This should ensure that in all normal cases none all or variables are
|
||||||
THD Thread id
|
updated.
|
||||||
set_var List of variables to update
|
|
||||||
|
|
||||||
DESCRIPTION
|
@param THD Thread id
|
||||||
First run a check of all variables that all updates will go ok.
|
@param var_list List of variables to update
|
||||||
If yes, then execute all updates, returning an error if any one failed.
|
|
||||||
|
|
||||||
This should ensure that in all normal cases none all or variables are
|
@retval
|
||||||
updated
|
|
||||||
|
|
||||||
RETURN VALUE
|
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 ERROR, message sent (normally no variables was updated)
|
1 ERROR, message sent (normally no variables was updated)
|
||||||
|
@retval
|
||||||
-1 ERROR, message not sent
|
-1 ERROR, message not sent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3103,20 +3112,19 @@ err:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Say if all variables set by a SET support the ONE_SHOT keyword (currently,
|
Say if all variables set by a SET support the ONE_SHOT keyword
|
||||||
only character set and collation do; later timezones will).
|
(currently, only character set and collation do; later timezones
|
||||||
|
will).
|
||||||
|
|
||||||
SYNOPSIS
|
@param var_list List of variables to update
|
||||||
|
|
||||||
not_all_support_one_shot
|
@note
|
||||||
set_var List of variables to update
|
|
||||||
|
|
||||||
NOTES
|
|
||||||
It has a "not_" because it makes faster tests (no need to "!")
|
It has a "not_" because it makes faster tests (no need to "!")
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 all variables of the list support ONE_SHOT
|
0 all variables of the list support ONE_SHOT
|
||||||
|
@retval
|
||||||
1 at least one does not support ONE_SHOT
|
1 at least one does not support ONE_SHOT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3175,17 +3183,17 @@ int set_var::check(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check variable, but without assigning value (used by PS)
|
Check variable, but without assigning value (used by PS).
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread handler
|
||||||
set_var::light_check()
|
|
||||||
thd thread handler
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 ERROR, message sent (normally no variables was updated)
|
1 ERROR, message sent (normally no variables was updated)
|
||||||
-1 ERROR, message not sent
|
@retval
|
||||||
|
-1 ERROR, message not sent
|
||||||
*/
|
*/
|
||||||
int set_var::light_check(THD *thd)
|
int set_var::light_check(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -3232,17 +3240,17 @@ int set_var_user::check(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check variable, but without assigning value (used by PS)
|
Check variable, but without assigning value (used by PS).
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread handler
|
||||||
set_var_user::light_check()
|
|
||||||
thd thread handler
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 ok
|
0 ok
|
||||||
|
@retval
|
||||||
1 ERROR, message sent (normally no variables was updated)
|
1 ERROR, message sent (normally no variables was updated)
|
||||||
-1 ERROR, message not sent
|
@retval
|
||||||
|
-1 ERROR, message not sent
|
||||||
*/
|
*/
|
||||||
int set_var_user::light_check(THD *thd)
|
int set_var_user::light_check(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -3416,13 +3424,15 @@ bool sys_var_thd_table_type::update(THD *thd, set_var *var)
|
||||||
Functions to handle sql_mode
|
Functions to handle sql_mode
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Make string representation of mode
|
Make string representation of mode.
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in] thd thread handler
|
||||||
thd in thread handler
|
@param[in] val sql_mode value
|
||||||
val in sql_mode value
|
@param[out] len pointer on length of string
|
||||||
rep out pointer pointer to string with sql_mode representation
|
|
||||||
|
@return
|
||||||
|
pointer to string with sql_mode representation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -3493,7 +3503,7 @@ void fix_sql_mode_var(THD *thd, enum_var_type type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map database specific bits to function bits */
|
/** Map database specific bits to function bits. */
|
||||||
|
|
||||||
ulong fix_sql_mode(ulong sql_mode)
|
ulong fix_sql_mode(ulong sql_mode)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
351
sql/sp.cc
351
sql/sp.cc
|
|
@ -249,19 +249,18 @@ Stored_routine_creation_ctx::load_from_db(THD *thd,
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Open the mysql.proc table for read.
|
Open the mysql.proc table for read.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
open_proc_table_for_read()
|
@param backup Pointer to Open_tables_state instance where information about
|
||||||
thd Thread context
|
currently open tables will be saved, and from which will be
|
||||||
backup Pointer to Open_tables_state instance where information about
|
restored when we will end work with mysql.proc.
|
||||||
currently open tables will be saved, and from which will be
|
|
||||||
restored when we will end work with mysql.proc.
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Error
|
0 Error
|
||||||
# Pointer to TABLE object of mysql.proc
|
@retval
|
||||||
|
\# Pointer to TABLE object of mysql.proc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
|
TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
|
||||||
|
|
@ -281,19 +280,18 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_state *backup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Open the mysql.proc table for update.
|
Open the mysql.proc table for update.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
open_proc_table_for_update()
|
|
||||||
thd Thread context
|
|
||||||
|
|
||||||
NOTES
|
@note
|
||||||
Table opened with this call should closed using close_thread_tables().
|
Table opened with this call should closed using close_thread_tables().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
0 Error
|
0 Error
|
||||||
# Pointer to TABLE object of mysql.proc
|
@retval
|
||||||
|
\# Pointer to TABLE object of mysql.proc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static TABLE *open_proc_table_for_update(THD *thd)
|
static TABLE *open_proc_table_for_update(THD *thd)
|
||||||
|
|
@ -310,19 +308,18 @@ static TABLE *open_proc_table_for_update(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find row in open mysql.proc table representing stored routine.
|
Find row in open mysql.proc table representing stored routine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
db_find_routine_aux()
|
@param type Type of routine to find (function or procedure)
|
||||||
thd Thread context
|
@param name Name of routine
|
||||||
type Type of routine to find (function or procedure)
|
@param table TABLE object for open mysql.proc table.
|
||||||
name Name of routine
|
|
||||||
table TABLE object for open mysql.proc table.
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
SP_OK - Routine found
|
SP_OK Routine found
|
||||||
SP_KEY_NOT_FOUND- No routine with given name
|
@retval
|
||||||
|
SP_KEY_NOT_FOUND No routine with given name
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -357,25 +354,24 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Find routine definition in mysql.proc table and create corresponding
|
Find routine definition in mysql.proc table and create corresponding
|
||||||
sp_head object for it.
|
sp_head object for it.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
db_find_routine()
|
@param type Type of routine (TYPE_ENUM_PROCEDURE/...)
|
||||||
thd Thread context
|
@param name Name of routine
|
||||||
type Type of routine (TYPE_ENUM_PROCEDURE/...)
|
@param sphp Out parameter in which pointer to created sp_head
|
||||||
name Name of routine
|
object is returned (0 in case of error).
|
||||||
sphp Out parameter in which pointer to created sp_head
|
|
||||||
object is returned (0 in case of error).
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This function may damage current LEX during execution, so it is good
|
This function may damage current LEX during execution, so it is good
|
||||||
idea to create temporary LEX and make it active before calling it.
|
idea to create temporary LEX and make it active before calling it.
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - Success
|
0 Success
|
||||||
non-0 - Error (may be one of special codes like SP_KEY_NOT_FOUND)
|
@retval
|
||||||
|
non-0 Error (may be one of special codes like SP_KEY_NOT_FOUND)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -1337,22 +1333,21 @@ sp_show_create_routine(THD *thd, int type, sp_name *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Obtain object representing stored procedure/function by its name from
|
Obtain object representing stored procedure/function by its name from
|
||||||
stored procedures cache and looking into mysql.proc if needed.
|
stored procedures cache and looking into mysql.proc if needed.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
sp_find_routine()
|
@param type type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
|
||||||
thd - thread context
|
@param name name of procedure
|
||||||
type - type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
|
@param cp hash to look routine in
|
||||||
name - name of procedure
|
@param cache_only if true perform cache-only lookup
|
||||||
cp - hash to look routine in
|
(Don't look in mysql.proc).
|
||||||
cache_only - if true perform cache-only lookup
|
|
||||||
(Don't look in mysql.proc).
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
Non-0 pointer to sp_head object for the procedure, or
|
NonNULL pointer to sp_head object for the procedure
|
||||||
0 - in case of error.
|
@retval
|
||||||
|
NULL in case of error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sp_head *
|
sp_head *
|
||||||
|
|
@ -1448,7 +1443,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
|
This is used by sql_acl.cc:mysql_routine_grant() and is used to find
|
||||||
the routines in 'routines'.
|
the routines in 'routines'.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1497,18 +1492,17 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if a routine exists in the mysql.proc table, without actually
|
Check if a routine exists in the mysql.proc table, without actually
|
||||||
parsing the definition. (Used for dropping)
|
parsing the definition. (Used for dropping).
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
sp_routine_exists_in_table()
|
@param name name of procedure
|
||||||
thd - thread context
|
|
||||||
name - name of procedure
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - Success
|
0 Success
|
||||||
non-0 - Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
|
@retval
|
||||||
|
non-0 Error; SP_OPEN_TABLE_FAILED or SP_KEY_NOT_FOUND
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -1530,7 +1524,7 @@ sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Structure that represents element in the set of stored routines
|
Structure that represents element in the set of stored routines
|
||||||
used by statement or routine.
|
used by statement or routine.
|
||||||
*/
|
*/
|
||||||
|
|
@ -1538,14 +1532,16 @@ struct Sroutine_hash_entry;
|
||||||
|
|
||||||
struct Sroutine_hash_entry
|
struct Sroutine_hash_entry
|
||||||
{
|
{
|
||||||
/* Set key consisting of one-byte routine type and quoted routine name. */
|
/**
|
||||||
|
Set key consisting of one-byte routine type and quoted routine name.
|
||||||
|
*/
|
||||||
LEX_STRING key;
|
LEX_STRING key;
|
||||||
/*
|
/**
|
||||||
Next element in list linking all routines in set. See also comments
|
Next element in list linking all routines in set. See also comments
|
||||||
for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
|
for LEX::sroutine/sroutine_list and sp_head::m_sroutines.
|
||||||
*/
|
*/
|
||||||
Sroutine_hash_entry *next;
|
Sroutine_hash_entry *next;
|
||||||
/*
|
/**
|
||||||
Uppermost view which directly or indirectly uses this routine.
|
Uppermost view which directly or indirectly uses this routine.
|
||||||
0 if routine is not used in view. Note that it also can be 0 if
|
0 if routine is not used in view. Note that it also can be 0 if
|
||||||
statement uses routine both via view and directly.
|
statement uses routine both via view and directly.
|
||||||
|
|
@ -1563,24 +1559,22 @@ extern "C" uchar* sp_sroutine_key(const uchar *ptr, size_t *plen,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if
|
Check if
|
||||||
- current statement (the one in thd->lex) needs table prelocking
|
- current statement (the one in thd->lex) needs table prelocking
|
||||||
- first routine in thd->lex->sroutines_list needs to execute its body in
|
- first routine in thd->lex->sroutines_list needs to execute its body in
|
||||||
prelocked mode.
|
prelocked mode.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Current thread, thd->lex is the statement to be
|
||||||
sp_get_prelocking_info()
|
checked.
|
||||||
thd Current thread, thd->lex is the statement to be
|
@param[out] need_prelocking TRUE - prelocked mode should be activated
|
||||||
checked.
|
before executing the statement;
|
||||||
need_prelocking OUT TRUE - prelocked mode should be activated
|
FALSE - Don't activate prelocking
|
||||||
before executing the statement
|
@param[out] first_no_prelocking TRUE - Tables used by first routine in
|
||||||
FALSE - Don't activate prelocking
|
thd->lex->sroutines_list should be
|
||||||
first_no_prelocking OUT TRUE - Tables used by first routine in
|
prelocked. FALSE - Otherwise.
|
||||||
thd->lex->sroutines_list should be
|
|
||||||
prelocked.
|
@note
|
||||||
FALSE - Otherwise.
|
|
||||||
NOTES
|
|
||||||
This function assumes that for any "CALL proc(...)" statement routines_list
|
This function assumes that for any "CALL proc(...)" statement routines_list
|
||||||
will have 'proc' as first element (it may have several, consider e.g.
|
will have 'proc' as first element (it may have several, consider e.g.
|
||||||
"proc(sp_func(...)))". This property is currently guaranted by the parser.
|
"proc(sp_func(...)))". This property is currently guaranted by the parser.
|
||||||
|
|
@ -1600,36 +1594,37 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Auxilary function that adds new element to the set of stored routines
|
Auxilary function that adds new element to the set of stored routines
|
||||||
used by statement.
|
used by statement.
|
||||||
|
|
||||||
SYNOPSIS
|
In case when statement uses stored routines but does not need
|
||||||
add_used_routine()
|
prelocking (i.e. it does not use any tables) we will access the
|
||||||
lex LEX representing statement
|
elements of LEX::sroutines set on prepared statement re-execution.
|
||||||
arena Arena in which memory for new element will be allocated
|
Because of this we have to allocate memory for both hash element
|
||||||
key Key for the hash representing set
|
and copy of its key in persistent arena.
|
||||||
belong_to_view Uppermost view which uses this routine
|
|
||||||
(0 if routine is not used by view)
|
|
||||||
|
|
||||||
NOTES
|
@param lex LEX representing statement
|
||||||
|
@param arena Arena in which memory for new element will be
|
||||||
|
allocated
|
||||||
|
@param key Key for the hash representing set
|
||||||
|
@param belong_to_view Uppermost view which uses this routine
|
||||||
|
(0 if routine is not used by view)
|
||||||
|
|
||||||
|
@note
|
||||||
Will also add element to end of 'LEX::sroutines_list' list.
|
Will also add element to end of 'LEX::sroutines_list' list.
|
||||||
|
|
||||||
In case when statement uses stored routines but does not need
|
@todo
|
||||||
prelocking (i.e. it does not use any tables) we will access the
|
|
||||||
elements of LEX::sroutines set on prepared statement re-execution.
|
|
||||||
Because of this we have to allocate memory for both hash element
|
|
||||||
and copy of its key in persistent arena.
|
|
||||||
|
|
||||||
TODO
|
|
||||||
When we will got rid of these accesses on re-executions we will be
|
When we will got rid of these accesses on re-executions we will be
|
||||||
able to allocate memory for hash elements in non-persitent arena
|
able to allocate memory for hash elements in non-persitent arena
|
||||||
and directly use key values from sp_head::m_sroutines sets instead
|
and directly use key values from sp_head::m_sroutines sets instead
|
||||||
of making their copies.
|
of making their copies.
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
TRUE - new element was added.
|
TRUE new element was added.
|
||||||
FALSE - element was not added (because it is already present in the set).
|
@retval
|
||||||
|
FALSE element was not added (because it is already present in
|
||||||
|
the set).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool add_used_routine(LEX *lex, Query_arena *arena,
|
static bool add_used_routine(LEX *lex, Query_arena *arena,
|
||||||
|
|
@ -1659,24 +1654,22 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add routine which is explicitly used by statement to the set of stored
|
Add routine which is explicitly used by statement to the set of stored
|
||||||
routines used by this statement.
|
routines used by this statement.
|
||||||
|
|
||||||
SYNOPSIS
|
To be friendly towards prepared statements one should pass
|
||||||
sp_add_used_routine()
|
persistent arena as second argument.
|
||||||
lex - LEX representing statement
|
|
||||||
arena - arena in which memory for new element of the set
|
|
||||||
will be allocated
|
|
||||||
rt - routine name
|
|
||||||
rt_type - routine type (one of TYPE_ENUM_PROCEDURE/...)
|
|
||||||
|
|
||||||
NOTES
|
@param lex LEX representing statement
|
||||||
|
@param arena arena in which memory for new element of the set
|
||||||
|
will be allocated
|
||||||
|
@param rt routine name
|
||||||
|
@param rt_type routine type (one of TYPE_ENUM_PROCEDURE/...)
|
||||||
|
|
||||||
|
@note
|
||||||
Will also add element to end of 'LEX::sroutines_list' list (and will
|
Will also add element to end of 'LEX::sroutines_list' list (and will
|
||||||
take into account that this is explicitly used routine).
|
take into account that this is explicitly used routine).
|
||||||
|
|
||||||
To be friendly towards prepared statements one should pass
|
|
||||||
persistent arena as second argument.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
||||||
|
|
@ -1689,13 +1682,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Remove routines which are only indirectly used by statement from
|
Remove routines which are only indirectly used by statement from
|
||||||
the set of routines used by this statement.
|
the set of routines used by this statement.
|
||||||
|
|
||||||
SYNOPSIS
|
@param lex LEX representing statement
|
||||||
sp_remove_not_own_routines()
|
|
||||||
lex LEX representing statement
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sp_remove_not_own_routines(LEX *lex)
|
void sp_remove_not_own_routines(LEX *lex)
|
||||||
|
|
@ -1718,16 +1709,14 @@ void sp_remove_not_own_routines(LEX *lex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Merge contents of two hashes representing sets of routines used
|
Merge contents of two hashes representing sets of routines used
|
||||||
by statements or by other routines.
|
by statements or by other routines.
|
||||||
|
|
||||||
SYNOPSIS
|
@param dst hash to which elements should be added
|
||||||
sp_update_sp_used_routines()
|
@param src hash from which elements merged
|
||||||
dst - hash to which elements should be added
|
|
||||||
src - hash from which elements merged
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This procedure won't create new Sroutine_hash_entry objects,
|
This procedure won't create new Sroutine_hash_entry objects,
|
||||||
instead it will simply add elements from source to destination
|
instead it will simply add elements from source to destination
|
||||||
hash. Thus time of life of elements in destination hash becomes
|
hash. Thus time of life of elements in destination hash becomes
|
||||||
|
|
@ -1747,18 +1736,17 @@ void sp_update_sp_used_routines(HASH *dst, HASH *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add contents of hash representing set of routines to the set of
|
Add contents of hash representing set of routines to the set of
|
||||||
routines used by statement.
|
routines used by statement.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
sp_update_stmt_used_routines()
|
@param lex LEX representing statement
|
||||||
thd Thread context
|
@param src Hash representing set from which routines will
|
||||||
lex LEX representing statement
|
be added
|
||||||
src Hash representing set from which routines will be added
|
@param belong_to_view Uppermost view which uses these routines, 0 if none
|
||||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
It will also add elements to end of 'LEX::sroutines_list' list.
|
It will also add elements to end of 'LEX::sroutines_list' list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1774,18 +1762,17 @@ sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add contents of list representing set of routines to the set of
|
Add contents of list representing set of routines to the set of
|
||||||
routines used by statement.
|
routines used by statement.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
sp_update_stmt_used_routines()
|
@param lex LEX representing statement
|
||||||
thd Thread context
|
@param src List representing set from which routines will
|
||||||
lex LEX representing statement
|
be added
|
||||||
src List representing set from which routines will be added
|
@param belong_to_view Uppermost view which uses these routines, 0 if none
|
||||||
belong_to_view Uppermost view which uses these routines, 0 if none
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
It will also add elements to end of 'LEX::sroutines_list' list.
|
It will also add elements to end of 'LEX::sroutines_list' list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1798,27 +1785,28 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Cache sub-set of routines used by statement, add tables used by these
|
Cache sub-set of routines used by statement, add tables used by these
|
||||||
routines to statement table list. Do the same for all routines used
|
routines to statement table list. Do the same for all routines used
|
||||||
by these routines.
|
by these routines.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
sp_cache_routines_and_add_tables_aux()
|
@param lex LEX representing statement
|
||||||
thd - thread context
|
@param start first routine from the list of routines to be cached
|
||||||
lex - LEX representing statement
|
(this list defines mentioned sub-set).
|
||||||
start - first routine from the list of routines to be cached
|
@param first_no_prelock If true, don't add tables or cache routines used by
|
||||||
(this list defines mentioned sub-set).
|
the body of the first routine (i.e. *start)
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
will be executed in non-prelocked mode.
|
||||||
the body of the first routine (i.e. *start)
|
@param tabs_changed Set to TRUE some tables were added, FALSE otherwise
|
||||||
will be executed in non-prelocked mode.
|
|
||||||
NOTE
|
@note
|
||||||
If some function is missing this won't be reported here.
|
If some function is missing this won't be reported here.
|
||||||
Instead this fact will be discovered during query execution.
|
Instead this fact will be discovered during query execution.
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - success
|
0 success
|
||||||
non-0 - failure
|
@retval
|
||||||
|
non-0 failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -1903,21 +1891,20 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Cache all routines from the set of used by statement, add tables used
|
Cache all routines from the set of used by statement, add tables used
|
||||||
by those routines to statement table list. Do the same for all routines
|
by those routines to statement table list. Do the same for all routines
|
||||||
used by those routines.
|
used by those routines.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
sp_cache_routines_and_add_tables()
|
@param lex LEX representing statement
|
||||||
thd - thread context
|
@param first_no_prelock If true, don't add tables or cache routines used by
|
||||||
lex - LEX representing statement
|
the body of the first routine (i.e. *start)
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
|
||||||
the body of the first routine (i.e. *start)
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - success
|
0 success
|
||||||
non-0 - failure
|
@retval
|
||||||
|
non-0 failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -1929,20 +1916,21 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add all routines used by view to the set of routines used by statement.
|
Add all routines used by view to the set of routines used by
|
||||||
|
statement.
|
||||||
|
|
||||||
Add tables used by those routines to statement table list. Do the same
|
Add tables used by those routines to statement table list. Do the same
|
||||||
for all routines used by these routines.
|
for all routines used by these routines.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
sp_cache_routines_and_add_tables_for_view()
|
@param lex LEX representing statement
|
||||||
thd Thread context
|
@param view Table list element representing view
|
||||||
lex LEX representing statement
|
|
||||||
view Table list element representing view
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - success
|
0 success
|
||||||
non-0 - failure
|
@retval
|
||||||
|
non-0 failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -1957,20 +1945,19 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add triggers for table to the set of routines used by statement.
|
Add triggers for table to the set of routines used by statement.
|
||||||
Add tables used by them to statement table list. Do the same for
|
Add tables used by them to statement table list. Do the same for
|
||||||
all implicitly used routines.
|
all implicitly used routines.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
sp_cache_routines_and_add_tables_for_triggers()
|
@param lex LEX respresenting statement
|
||||||
thd thread context
|
@param table Table list element for table with trigger
|
||||||
lex LEX respresenting statement
|
|
||||||
table Table list element for table with trigger
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 - success
|
0 success
|
||||||
non-0 - failure
|
@retval
|
||||||
|
non-0 failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -2016,10 +2003,12 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Generates the CREATE... string from the table information.
|
Generates the CREATE... string from the table information.
|
||||||
* Returns TRUE on success, FALSE on (alloc) failure.
|
|
||||||
*/
|
@return
|
||||||
|
Returns TRUE on success, FALSE on (alloc) failure.
|
||||||
|
*/
|
||||||
static bool
|
static bool
|
||||||
create_string(THD *thd, String *buf,
|
create_string(THD *thd, String *buf,
|
||||||
int type,
|
int type,
|
||||||
|
|
|
||||||
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.
|
Return a string representation of the Item value.
|
||||||
|
|
||||||
NOTE: If the item has a string result type, the string is escaped
|
@param thd thread handle
|
||||||
according to its character set.
|
@param str string buffer for representation of the value
|
||||||
|
|
||||||
SYNOPSIS
|
@note
|
||||||
item a pointer to the Item
|
If the item has a string result type, the string is escaped
|
||||||
str string buffer for representation of the value
|
according to its character set.
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL on error
|
NULL on error
|
||||||
a pointer to valid a valid string on success
|
@retval
|
||||||
|
non-NULL a pointer to valid a valid string on success
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static String *
|
static String *
|
||||||
|
|
@ -138,16 +139,12 @@ sp_get_item_value(THD *thd, Item *item, String *str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
SYNOPSIS
|
Returns a combination of:
|
||||||
sp_get_flags_for_command()
|
- sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
|
||||||
|
result in multiple result sets being sent back.
|
||||||
DESCRIPTION
|
- sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
|
||||||
Returns a combination of:
|
EXECUTE, DEALLOCATE.
|
||||||
* sp_head::MULTI_RESULTS: added if the 'cmd' is a command that might
|
|
||||||
result in multiple result sets being sent back.
|
|
||||||
* sp_head::CONTAINS_DYNAMIC_SQL: added if 'cmd' is one of PREPARE,
|
|
||||||
EXECUTE, DEALLOCATE.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint
|
uint
|
||||||
|
|
@ -287,17 +284,16 @@ sp_get_flags_for_command(LEX *lex)
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare an Item for evaluation (call of fix_fields).
|
Prepare an Item for evaluation (call of fix_fields).
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread handler
|
||||||
sp_prepare_func_item()
|
@param it_addr pointer on item refernce
|
||||||
thd thread handler
|
|
||||||
it_addr pointer on item refernce
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
NULL error
|
NULL error
|
||||||
prepared item
|
@retval
|
||||||
|
non-NULL prepared item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item *
|
Item *
|
||||||
|
|
@ -317,17 +313,16 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Evaluate an expression and store the result in the field.
|
Evaluate an expression and store the result in the field.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread object
|
||||||
sp_eval_expr()
|
@param result_field the field to store the result
|
||||||
thd - current thread object
|
@param expr_item_ptr the root item of the expression
|
||||||
expr_item - the root item of the expression
|
|
||||||
result_field - the field to store the result
|
|
||||||
|
|
||||||
RETURN VALUES
|
@retval
|
||||||
FALSE on success
|
FALSE on success
|
||||||
|
@retval
|
||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -410,6 +405,10 @@ sp_name::sp_name(THD *thd, char *key, uint key_len)
|
||||||
m_explicit_name= false;
|
m_explicit_name= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Init the qualified name from the db and name.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
sp_name::init_qname(THD *thd)
|
sp_name::init_qname(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -427,16 +426,17 @@ sp_name::init_qname(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check that the name 'ident' is ok. It's assumed to be an 'ident'
|
Check that the name 'ident' is ok. It's assumed to be an 'ident'
|
||||||
from the parser, so we only have to check length and trailing spaces.
|
from the parser, so we only have to check length and trailing spaces.
|
||||||
The former is a standard requirement (and 'show status' assumes a
|
The former is a standard requirement (and 'show status' assumes a
|
||||||
non-empty name), the latter is a mysql:ism as trailing spaces are
|
non-empty name), the latter is a mysql:ism as trailing spaces are
|
||||||
removed by get_field().
|
removed by get_field().
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
TRUE - bad name
|
TRUE bad name
|
||||||
FALSE - name is ok
|
@retval
|
||||||
|
FALSE name is ok
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -444,7 +444,7 @@ check_routine_name(LEX_STRING *ident)
|
||||||
{
|
{
|
||||||
if (!ident || !ident->str || !ident->str[0] ||
|
if (!ident || !ident->str || !ident->str[0] ||
|
||||||
ident->str[ident->length-1] == ' ')
|
ident->str[ident->length-1] == ' ')
|
||||||
{
|
{
|
||||||
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
|
my_error(ER_SP_WRONG_NAME, MYF(0), ident->str);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -778,7 +778,7 @@ sp_head::destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This is only used for result fields from functions (both during
|
This is only used for result fields from functions (both during
|
||||||
fix_length_and_dec() and evaluation).
|
fix_length_and_dec() and evaluation).
|
||||||
*/
|
*/
|
||||||
|
|
@ -897,29 +897,23 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Replace thd->query{_length} with a string that one can write to the binlog
|
Replace thd->query{_length} with a string that one can write to
|
||||||
or the query cache.
|
the binlog.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
subst_spvars()
|
|
||||||
thd Current thread.
|
|
||||||
instr Instruction (we look for Item_splocal instances in
|
|
||||||
instr->free_list)
|
|
||||||
query_str Original query string
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
|
|
||||||
The binlog-suitable string is produced by replacing references to SP local
|
The binlog-suitable string is produced by replacing references to SP local
|
||||||
variables with NAME_CONST('sp_var_name', value) calls. To make this string
|
variables with NAME_CONST('sp_var_name', value) calls.
|
||||||
suitable for the query cache this function allocates some additional space
|
|
||||||
for the query cache flags.
|
@param thd Current thread.
|
||||||
|
@param instr Instruction (we look for Item_splocal instances in
|
||||||
RETURN
|
instr->free_list)
|
||||||
FALSE on success
|
@param query_str Original query string
|
||||||
thd->query{_length} either has been appropriately replaced or there
|
|
||||||
is no need for replacements.
|
@return
|
||||||
TRUE out of memory error.
|
- FALSE on success.
|
||||||
|
thd->query{_length} either has been appropriately replaced or there
|
||||||
|
is no need for replacements.
|
||||||
|
- TRUE out of memory error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
@ -1038,14 +1032,17 @@ void sp_head::recursion_level_error(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute the routine. The main instruction jump loop is there
|
Execute the routine. The main instruction jump loop is there.
|
||||||
Assume the parameters already set.
|
Assume the parameters already set.
|
||||||
|
@todo
|
||||||
RETURN
|
- Will write this SP statement into binlog separately
|
||||||
FALSE on success
|
(TODO: consider changing the condition to "not inside event union")
|
||||||
TRUE on error
|
|
||||||
|
|
||||||
|
@retval
|
||||||
|
FALSE on success
|
||||||
|
@retval
|
||||||
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1335,22 +1332,26 @@ sp_head::execute(THD *thd)
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/*
|
/**
|
||||||
set_routine_security_ctx() changes routine security context, and
|
set_routine_security_ctx() changes routine security context, and
|
||||||
checks if there is an EXECUTE privilege in new context. If there is
|
checks if there is an EXECUTE privilege in new context. If there is
|
||||||
no EXECUTE privilege, it changes the context back and returns a
|
no EXECUTE privilege, it changes the context back and returns a
|
||||||
error.
|
error.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread handle
|
||||||
set_routine_security_ctx()
|
@param sp stored routine to change the context for
|
||||||
thd thread handle
|
@param is_proc TRUE is procedure, FALSE if function
|
||||||
sp stored routine to change the context for
|
@param save_ctx pointer to an old security context
|
||||||
is_proc TRUE is procedure, FALSE if function
|
|
||||||
save_ctx pointer to an old security context
|
@todo
|
||||||
|
- Cache if the definer has the right to use the object on the
|
||||||
RETURN
|
first usage and only reset the cache if someone does a GRANT
|
||||||
TRUE if there was a error, and the context wasn't changed.
|
statement that 'may' affect this.
|
||||||
FALSE if the context was changed.
|
|
||||||
|
@retval
|
||||||
|
TRUE if there was a error, and the context wasn't changed.
|
||||||
|
@retval
|
||||||
|
FALSE if the context was changed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1392,22 +1393,27 @@ set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc,
|
||||||
/**
|
/**
|
||||||
Execute trigger stored program.
|
Execute trigger stored program.
|
||||||
|
|
||||||
Execute a trigger:
|
- changes security context for triggers
|
||||||
- changes security context for triggers;
|
- switch to new memroot
|
||||||
- switch to new memroot;
|
- call sp_head::execute
|
||||||
- call sp_head::execute;
|
- restore old memroot
|
||||||
- restore old memroot;
|
- restores security context
|
||||||
- restores security context.
|
|
||||||
|
|
||||||
@param thd Thread context.
|
@param thd Thread handle
|
||||||
@param db_name Database name.
|
@param db database name
|
||||||
@param table_name Table name.
|
@param table table name
|
||||||
@param grant_info GRANT_INFO structure to be filled with information
|
@param grant_info GRANT_INFO structure to be filled with
|
||||||
about definer's privileges on subject table.
|
information about definer's privileges
|
||||||
|
on subject table
|
||||||
|
|
||||||
@return Error status.
|
@todo
|
||||||
@retval FALSE on success.
|
- TODO: we should create sp_rcontext once per command and reuse it
|
||||||
@retval TRUE on error.
|
on subsequent executions of a trigger.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
FALSE on success
|
||||||
|
@retval
|
||||||
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -1515,8 +1521,9 @@ err_with_cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute a function:
|
Execute a function.
|
||||||
|
|
||||||
- evaluate parameters
|
- evaluate parameters
|
||||||
- changes security context for SUID routines
|
- changes security context for SUID routines
|
||||||
- switch to new memroot
|
- switch to new memroot
|
||||||
|
|
@ -1525,17 +1532,25 @@ err_with_cleanup:
|
||||||
- evaluate the return value
|
- evaluate the return value
|
||||||
- restores security context
|
- restores security context
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handle
|
||||||
sp_head::execute_function()
|
@param argp Passed arguments (these are items from containing
|
||||||
thd Thread handle
|
statement?)
|
||||||
argp Passed arguments (these are items from containing
|
@param argcount Number of passed arguments. We need to check if
|
||||||
statement?)
|
this is correct.
|
||||||
argcount Number of passed arguments. We need to check if this is
|
@param return_value_fld Save result here.
|
||||||
correct.
|
|
||||||
return_value_fld Save result here.
|
@todo
|
||||||
|
We should create sp_rcontext once per command and reuse
|
||||||
RETURN
|
it on subsequent executions of a function/trigger.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
In future we should associate call arena/mem_root with
|
||||||
|
sp_rcontext and allocate all these objects (and sp_rcontext
|
||||||
|
itself) on it directly rather than juggle with arenas.
|
||||||
|
|
||||||
|
@retval
|
||||||
FALSE on success
|
FALSE on success
|
||||||
|
@retval
|
||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1752,14 +1767,8 @@ err_with_cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute a procedure.
|
Execute a procedure.
|
||||||
SYNOPSIS
|
|
||||||
sp_head::execute_procedure()
|
|
||||||
thd Thread handle
|
|
||||||
args List of values passed as arguments.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
|
|
||||||
The function does the following steps:
|
The function does the following steps:
|
||||||
- Set all parameters
|
- Set all parameters
|
||||||
|
|
@ -1768,8 +1777,12 @@ err_with_cleanup:
|
||||||
- copy back values of INOUT and OUT parameters
|
- copy back values of INOUT and OUT parameters
|
||||||
- restores security context
|
- restores security context
|
||||||
|
|
||||||
RETURN
|
@param thd Thread handle
|
||||||
|
@param args List of values passed as arguments.
|
||||||
|
|
||||||
|
@retval
|
||||||
FALSE on success
|
FALSE on success
|
||||||
|
@retval
|
||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1972,7 +1985,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Reset lex during parsing, before we parse a sub statement.
|
Reset lex during parsing, before we parse a sub statement.
|
||||||
|
|
||||||
@param thd Thread handler.
|
@param thd Thread handler.
|
||||||
|
|
||||||
|
|
@ -2017,7 +2030,7 @@ sp_head::reset_lex(THD *thd)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore lex during parsing, after we have parsed a sub statement.
|
/// Restore lex during parsing, after we have parsed a sub statement.
|
||||||
void
|
void
|
||||||
sp_head::restore_lex(THD *thd)
|
sp_head::restore_lex(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -2060,6 +2073,9 @@ sp_head::restore_lex(THD *thd)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Put the instruction on the backpatch list, associated with the label.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
|
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
|
||||||
{
|
{
|
||||||
|
|
@ -2073,6 +2089,10 @@ sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update all instruction with this label in the backpatch list to
|
||||||
|
the current position.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
sp_head::backpatch(sp_label_t *lab)
|
sp_head::backpatch(sp_label_t *lab)
|
||||||
{
|
{
|
||||||
|
|
@ -2087,19 +2107,18 @@ sp_head::backpatch(sp_label_t *lab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare an instance of Create_field for field creation (fill all necessary
|
Prepare an instance of Create_field for field creation (fill all necessary
|
||||||
attributes).
|
attributes).
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in] thd Thread handle
|
||||||
sp_head::fill_field_definition()
|
@param[in] lex Yacc parsing context
|
||||||
thd [IN] Thread handle
|
@param[in] field_type Field type
|
||||||
lex [IN] Yacc parsing context
|
@param[out] field_def An instance of create_field to be filled
|
||||||
field_type [IN] Field type
|
|
||||||
field_def [OUT] An instance of Create_field to be filled
|
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE on success
|
FALSE on success
|
||||||
|
@retval
|
||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2245,18 +2264,17 @@ sp_head::restore_thd_mem_root(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if a user has access right to a routine
|
Check if a user has access right to a routine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread handler
|
||||||
check_show_routine_access()
|
@param sp SP
|
||||||
thd Thread handler
|
@param full_access Set to 1 if the user has SELECT right to the
|
||||||
sp SP
|
'mysql.proc' able or is the owner of the routine
|
||||||
full_access Set to 1 if the user has SELECT right to the
|
@retval
|
||||||
'mysql.proc' able or is the owner of the routine
|
false ok
|
||||||
RETURN
|
@retval
|
||||||
0 ok
|
true error
|
||||||
1 error
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
|
bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access)
|
||||||
|
|
@ -2383,12 +2401,10 @@ sp_head::show_create_routine(THD *thd, int type)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add instruction to SP
|
Add instruction to SP.
|
||||||
|
|
||||||
SYNOPSIS
|
@param instr Instruction
|
||||||
sp_head::add_instr()
|
|
||||||
instr Instruction
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sp_head::add_instr(sp_instr *instr)
|
void sp_head::add_instr(sp_instr *instr)
|
||||||
|
|
@ -2406,20 +2422,20 @@ void sp_head::add_instr(sp_instr *instr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Do some minimal optimization of the code:
|
Do some minimal optimization of the code:
|
||||||
1) Mark used instructions
|
-# Mark used instructions
|
||||||
1.1) While doing this, shortcut jumps to jump instructions
|
-# While doing this, shortcut jumps to jump instructions
|
||||||
2) Compact the code, removing unused instructions
|
-# Compact the code, removing unused instructions.
|
||||||
|
|
||||||
This is the main mark and move loop; it relies on the following methods
|
This is the main mark and move loop; it relies on the following methods
|
||||||
in sp_instr and its subclasses:
|
in sp_instr and its subclasses:
|
||||||
|
|
||||||
opt_mark() Mark instruction as reachable
|
- opt_mark() : Mark instruction as reachable
|
||||||
opt_shortcut_jump() Shortcut jumps to the final destination;
|
- opt_shortcut_jump(): Shortcut jumps to the final destination;
|
||||||
used by opt_mark().
|
used by opt_mark().
|
||||||
opt_move() Update moved instruction
|
- opt_move() : Update moved instruction
|
||||||
set_destination() Set the new destination (jump instructions only)
|
- set_destination() : Set the new destination (jump instructions only)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void sp_head::optimize()
|
void sp_head::optimize()
|
||||||
|
|
@ -2510,9 +2526,10 @@ sp_head::opt_mark()
|
||||||
|
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
/*
|
/**
|
||||||
Return the routine instructions as a result set.
|
Return the routine instructions as a result set.
|
||||||
Returns 0 if ok, !=0 on error.
|
@return
|
||||||
|
0 if ok, !=0 on error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sp_head::show_routine_code(THD *thd)
|
sp_head::show_routine_code(THD *thd)
|
||||||
|
|
@ -2575,27 +2592,25 @@ sp_head::show_routine_code(THD *thd)
|
||||||
#endif // ifndef DBUG_OFF
|
#endif // ifndef DBUG_OFF
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare LEX and thread for execution of instruction, if requested open
|
Prepare LEX and thread for execution of instruction, if requested open
|
||||||
and lock LEX's tables, execute instruction's core function, perform
|
and lock LEX's tables, execute instruction's core function, perform
|
||||||
cleanup afterwards.
|
cleanup afterwards.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
reset_lex_and_exec_core()
|
@param nextp out - next instruction
|
||||||
thd - thread context
|
@param open_tables if TRUE then check read access to tables in LEX's table
|
||||||
nextp - out - next instruction
|
list and open and lock them (used in instructions which
|
||||||
open_tables - if TRUE then check read access to tables in LEX's table
|
need to calculate some expression and don't execute
|
||||||
list and open and lock them (used in instructions which
|
complete statement).
|
||||||
need to calculate some expression and don't execute
|
@param sp_instr instruction for which we prepare context, and which core
|
||||||
complete statement).
|
function execute by calling its exec_core() method.
|
||||||
sp_instr - instruction for which we prepare context, and which core
|
|
||||||
function execute by calling its exec_core() method.
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
We are not saving/restoring some parts of THD which may need this because
|
We are not saving/restoring some parts of THD which may need this because
|
||||||
we do this once for whole routine execution in sp_head::execute().
|
we do this once for whole routine execution in sp_head::execute().
|
||||||
|
|
||||||
RETURN VALUE
|
@return
|
||||||
0/non-0 - Success/Failure
|
0/non-0 - Success/Failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -3349,6 +3364,11 @@ sp_instr_cpop::print(String *str)
|
||||||
sp_instr_copen class functions
|
sp_instr_copen class functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Assert that we either have an error or a cursor
|
||||||
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
sp_instr_copen::execute(THD *thd, uint *nextp)
|
sp_instr_copen::execute(THD *thd, uint *nextp)
|
||||||
{
|
{
|
||||||
|
|
@ -3670,24 +3690,23 @@ uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Merge the list of tables used by some query into the multi-set of
|
Merge the list of tables used by some query into the multi-set of
|
||||||
tables used by routine.
|
tables used by routine.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread context
|
||||||
merge_table_list()
|
@param table table list
|
||||||
thd - thread context
|
@param lex_for_tmp_check LEX of the query for which we are merging
|
||||||
table - table list
|
table list.
|
||||||
lex_for_tmp_check - LEX of the query for which we are merging
|
|
||||||
table list.
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This method will use LEX provided to check whenever we are creating
|
This method will use LEX provided to check whenever we are creating
|
||||||
temporary table and mark it as such in target multi-set.
|
temporary table and mark it as such in target multi-set.
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
TRUE - Success
|
TRUE Success
|
||||||
FALSE - Error
|
@retval
|
||||||
|
FALSE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -3775,27 +3794,26 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Add tables used by routine to the table list.
|
Add tables used by routine to the table list.
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
add_used_tables_to_table_list()
|
|
||||||
thd [in] Thread context
|
|
||||||
query_tables_last_ptr [in/out] Pointer to the next_global member of
|
|
||||||
last element of the list where tables
|
|
||||||
will be added (or to its root).
|
|
||||||
belong_to_view [in] Uppermost view which uses this routine,
|
|
||||||
0 if none.
|
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Converts multi-set of tables used by this routine to table list and adds
|
Converts multi-set of tables used by this routine to table list and adds
|
||||||
this list to the end of table list specified by 'query_tables_last_ptr'.
|
this list to the end of table list specified by 'query_tables_last_ptr'.
|
||||||
|
|
||||||
Elements of list will be allocated in PS memroot, so this list will be
|
Elements of list will be allocated in PS memroot, so this list will be
|
||||||
persistent between PS executions.
|
persistent between PS executions.
|
||||||
|
|
||||||
RETURN VALUE
|
@param[in] thd Thread context
|
||||||
TRUE - if some elements were added, FALSE - otherwise.
|
@param[in,out] query_tables_last_ptr Pointer to the next_global member of
|
||||||
|
last element of the list where tables
|
||||||
|
will be added (or to its root).
|
||||||
|
@param[in] belong_to_view Uppermost view which uses this routine,
|
||||||
|
0 if none.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
TRUE if some elements were added
|
||||||
|
@retval
|
||||||
|
FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -3865,7 +3883,7 @@ sp_head::add_used_tables_to_table_list(THD *thd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Simple function for adding an explicetly named (systems) table to
|
Simple function for adding an explicetly named (systems) table to
|
||||||
the global table list, e.g. "mysql", "proc".
|
the global table list, e.g. "mysql", "proc".
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
217
sql/sp_head.h
217
sql/sp_head.h
|
|
@ -109,7 +109,7 @@ public:
|
||||||
LEX_STRING m_db;
|
LEX_STRING m_db;
|
||||||
LEX_STRING m_name;
|
LEX_STRING m_name;
|
||||||
LEX_STRING m_qname;
|
LEX_STRING m_qname;
|
||||||
/*
|
/**
|
||||||
Key representing routine in the set of stored routines used by statement.
|
Key representing routine in the set of stored routines used by statement.
|
||||||
Consists of 1-byte routine type and m_qname (which usually refences to
|
Consists of 1-byte routine type and m_qname (which usually refences to
|
||||||
same buffer). Note that one must complete initialization of the key by
|
same buffer). Note that one must complete initialization of the key by
|
||||||
|
|
@ -125,7 +125,7 @@ public:
|
||||||
m_qname.length= m_sroutines_key.length= 0;
|
m_qname.length= m_sroutines_key.length= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Creates temporary sp_name object from key, used mainly
|
Creates temporary sp_name object from key, used mainly
|
||||||
for SP-cache lookups.
|
for SP-cache lookups.
|
||||||
*/
|
*/
|
||||||
|
|
@ -149,12 +149,12 @@ check_routine_name(LEX_STRING *ident);
|
||||||
|
|
||||||
class sp_head :private Query_arena
|
class sp_head :private Query_arena
|
||||||
{
|
{
|
||||||
sp_head(const sp_head &); /* Prevent use of these */
|
sp_head(const sp_head &); /**< Prevent use of these */
|
||||||
void operator=(sp_head &);
|
void operator=(sp_head &);
|
||||||
|
|
||||||
MEM_ROOT main_mem_root;
|
MEM_ROOT main_mem_root;
|
||||||
public:
|
public:
|
||||||
/* Possible values of m_flags */
|
/** Possible values of m_flags */
|
||||||
enum {
|
enum {
|
||||||
HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
|
HAS_RETURN= 1, // For FUNCTIONs only: is set if has RETURN
|
||||||
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
|
MULTI_RESULTS= 8, // Is set if a procedure with SELECT(s)
|
||||||
|
|
@ -170,16 +170,16 @@ public:
|
||||||
HAS_SQLCOM_FLUSH= 4096
|
HAS_SQLCOM_FLUSH= 4096
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
|
/** TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
|
||||||
int m_type;
|
int m_type;
|
||||||
uint m_flags; // Boolean attributes of a stored routine
|
uint m_flags; // Boolean attributes of a stored routine
|
||||||
|
|
||||||
Create_field m_return_field_def; /* This is used for FUNCTIONs only. */
|
Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */
|
||||||
|
|
||||||
const char *m_tmp_query; // Temporary pointer to sub query string
|
const char *m_tmp_query; ///< Temporary pointer to sub query string
|
||||||
st_sp_chistics *m_chistics;
|
st_sp_chistics *m_chistics;
|
||||||
ulong m_sql_mode; // For SHOW CREATE and execution
|
ulong m_sql_mode; ///< For SHOW CREATE and execution
|
||||||
LEX_STRING m_qname; // db.name
|
LEX_STRING m_qname; ///< db.name
|
||||||
/**
|
/**
|
||||||
Key representing routine in the set of stored routines used by statement.
|
Key representing routine in the set of stored routines used by statement.
|
||||||
[routine_type]db.name
|
[routine_type]db.name
|
||||||
|
|
@ -211,20 +211,20 @@ public:
|
||||||
|
|
||||||
longlong m_created;
|
longlong m_created;
|
||||||
longlong m_modified;
|
longlong m_modified;
|
||||||
/* Recursion level of the current SP instance. The levels are numbered from 0 */
|
/** Recursion level of the current SP instance. The levels are numbered from 0 */
|
||||||
ulong m_recursion_level;
|
ulong m_recursion_level;
|
||||||
/*
|
/**
|
||||||
A list of diferent recursion level instances for the same procedure.
|
A list of diferent recursion level instances for the same procedure.
|
||||||
For every recursion level we have a sp_head instance. This instances
|
For every recursion level we have a sp_head instance. This instances
|
||||||
connected in the list. The list ordered by increasing recursion level
|
connected in the list. The list ordered by increasing recursion level
|
||||||
(m_recursion_level).
|
(m_recursion_level).
|
||||||
*/
|
*/
|
||||||
sp_head *m_next_cached_sp;
|
sp_head *m_next_cached_sp;
|
||||||
/*
|
/**
|
||||||
Pointer to the first element of the above list
|
Pointer to the first element of the above list
|
||||||
*/
|
*/
|
||||||
sp_head *m_first_instance;
|
sp_head *m_first_instance;
|
||||||
/*
|
/**
|
||||||
Pointer to the first free (non-INVOKED) routine in the list of
|
Pointer to the first free (non-INVOKED) routine in the list of
|
||||||
cached instances for this SP. This pointer is set only for the first
|
cached instances for this SP. This pointer is set only for the first
|
||||||
SP in the list of instences (see above m_first_cached_sp pointer).
|
SP in the list of instences (see above m_first_cached_sp pointer).
|
||||||
|
|
@ -232,12 +232,12 @@ public:
|
||||||
For non-first instance value of this pointer meanless (point to itself);
|
For non-first instance value of this pointer meanless (point to itself);
|
||||||
*/
|
*/
|
||||||
sp_head *m_first_free_instance;
|
sp_head *m_first_free_instance;
|
||||||
/*
|
/**
|
||||||
Pointer to the last element in the list of instances of the SP.
|
Pointer to the last element in the list of instances of the SP.
|
||||||
For non-first instance value of this pointer meanless (point to itself);
|
For non-first instance value of this pointer meanless (point to itself);
|
||||||
*/
|
*/
|
||||||
sp_head *m_last_cached_sp;
|
sp_head *m_last_cached_sp;
|
||||||
/*
|
/**
|
||||||
Set containing names of stored routines used by this routine.
|
Set containing names of stored routines used by this routine.
|
||||||
Note that unlike elements of similar set for statement elements of this
|
Note that unlike elements of similar set for statement elements of this
|
||||||
set are not linked in one list. Because of this we are able save memory
|
set are not linked in one list. Because of this we are able save memory
|
||||||
|
|
@ -267,11 +267,11 @@ public:
|
||||||
|
|
||||||
sp_head();
|
sp_head();
|
||||||
|
|
||||||
// Initialize after we have reset mem_root
|
/// Initialize after we have reset mem_root
|
||||||
void
|
void
|
||||||
init(LEX *lex);
|
init(LEX *lex);
|
||||||
|
|
||||||
/* Copy sp name from parser. */
|
/** Copy sp name from parser. */
|
||||||
void
|
void
|
||||||
init_sp_name(THD *thd, sp_name *spname);
|
init_sp_name(THD *thd, sp_name *spname);
|
||||||
|
|
||||||
|
|
@ -288,7 +288,7 @@ public:
|
||||||
|
|
||||||
virtual ~sp_head();
|
virtual ~sp_head();
|
||||||
|
|
||||||
// Free memory
|
/// Free memory
|
||||||
void
|
void
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
|
@ -325,33 +325,41 @@ public:
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resets lex in 'thd' and keeps a copy of the old one.
|
/*
|
||||||
|
Resets lex in 'thd' and keeps a copy of the old one.
|
||||||
|
|
||||||
|
@todo Conflicting comment in sp_head.cc
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
reset_lex(THD *thd);
|
reset_lex(THD *thd);
|
||||||
|
|
||||||
// Restores lex in 'thd' from our copy, but keeps some status from the
|
/**
|
||||||
// one in 'thd', like ptr, tables, fields, etc.
|
Restores lex in 'thd' from our copy, but keeps some status from the
|
||||||
|
one in 'thd', like ptr, tables, fields, etc.
|
||||||
|
|
||||||
|
@todo Conflicting comment in sp_head.cc
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
restore_lex(THD *thd);
|
restore_lex(THD *thd);
|
||||||
|
|
||||||
// Put the instruction on the backpatch list, associated with the label.
|
/// Put the instruction on the backpatch list, associated with the label.
|
||||||
void
|
void
|
||||||
push_backpatch(sp_instr *, struct sp_label *);
|
push_backpatch(sp_instr *, struct sp_label *);
|
||||||
|
|
||||||
// Update all instruction with this label in the backpatch list to
|
/// Update all instruction with this label in the backpatch list to
|
||||||
// the current position.
|
/// the current position.
|
||||||
void
|
void
|
||||||
backpatch(struct sp_label *);
|
backpatch(struct sp_label *);
|
||||||
|
|
||||||
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
|
/// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
|
||||||
void
|
void
|
||||||
new_cont_backpatch(sp_instr_opt_meta *i);
|
new_cont_backpatch(sp_instr_opt_meta *i);
|
||||||
|
|
||||||
// Add an instruction to the current level
|
/// Add an instruction to the current level
|
||||||
void
|
void
|
||||||
add_cont_backpatch(sp_instr_opt_meta *i);
|
add_cont_backpatch(sp_instr_opt_meta *i);
|
||||||
|
|
||||||
// Backpatch (and pop) the current level to the current position.
|
/// Backpatch (and pop) the current level to the current position.
|
||||||
void
|
void
|
||||||
do_cont_backpatch();
|
do_cont_backpatch();
|
||||||
|
|
||||||
|
|
@ -414,7 +422,7 @@ public:
|
||||||
TABLE_LIST ***query_tables_last_ptr,
|
TABLE_LIST ***query_tables_last_ptr,
|
||||||
TABLE_LIST *belong_to_view);
|
TABLE_LIST *belong_to_view);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check if this stored routine contains statements disallowed
|
Check if this stored routine contains statements disallowed
|
||||||
in a stored function or trigger, and set an appropriate error message
|
in a stored function or trigger, and set an appropriate error message
|
||||||
if this is the case.
|
if this is the case.
|
||||||
|
|
@ -463,19 +471,19 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
|
MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root
|
||||||
THD *m_thd; // Set if we have reset mem_root
|
THD *m_thd; ///< Set if we have reset mem_root
|
||||||
|
|
||||||
sp_pcontext *m_pcont; // Parse context
|
sp_pcontext *m_pcont; ///< Parse context
|
||||||
List<LEX> m_lex; // Temp. store for the other lex
|
List<LEX> m_lex; ///< Temp. store for the other lex
|
||||||
DYNAMIC_ARRAY m_instr; // The "instructions"
|
DYNAMIC_ARRAY m_instr; ///< The "instructions"
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
struct sp_label *lab;
|
struct sp_label *lab;
|
||||||
sp_instr *instr;
|
sp_instr *instr;
|
||||||
} bp_t;
|
} bp_t;
|
||||||
List<bp_t> m_backpatch; // Instructions needing backpatching
|
List<bp_t> m_backpatch; ///< Instructions needing backpatching
|
||||||
/*
|
/**
|
||||||
We need a special list for backpatching of instructions with a continue
|
We need a special list for backpatching of instructions with a continue
|
||||||
destination (in the case of a continue handler catching an error in
|
destination (in the case of a continue handler catching an error in
|
||||||
the test), since it would otherwise interfere with the normal backpatch
|
the test), since it would otherwise interfere with the normal backpatch
|
||||||
|
|
@ -483,15 +491,16 @@ private:
|
||||||
which are to be patched differently.
|
which are to be patched differently.
|
||||||
Since these occur in a more restricted way (always the same "level" in
|
Since these occur in a more restricted way (always the same "level" in
|
||||||
the code), we don't need the label.
|
the code), we don't need the label.
|
||||||
*/
|
*/
|
||||||
List<sp_instr_opt_meta> m_cont_backpatch;
|
List<sp_instr_opt_meta> m_cont_backpatch;
|
||||||
uint m_cont_level; // The current cont. backpatch level
|
uint m_cont_level; // The current cont. backpatch level
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Multi-set representing optimized list of tables to be locked by this
|
Multi-set representing optimized list of tables to be locked by this
|
||||||
routine. Does not include tables which are used by invoked routines.
|
routine. Does not include tables which are used by invoked routines.
|
||||||
|
|
||||||
Note: for prelocking-free SPs this multiset is constructed too.
|
@note
|
||||||
|
For prelocking-free SPs this multiset is constructed too.
|
||||||
We do so because the same instance of sp_head may be called both
|
We do so because the same instance of sp_head may be called both
|
||||||
in prelocked mode and in non-prelocked mode.
|
in prelocked mode and in non-prelocked mode.
|
||||||
*/
|
*/
|
||||||
|
|
@ -506,7 +515,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void opt_mark();
|
void opt_mark();
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Merge the list of tables used by query into the multi-set of tables used
|
Merge the list of tables used by query into the multi-set of tables used
|
||||||
by routine.
|
by routine.
|
||||||
*/
|
*/
|
||||||
|
|
@ -520,16 +529,16 @@ private:
|
||||||
|
|
||||||
class sp_instr :public Query_arena, public Sql_alloc
|
class sp_instr :public Query_arena, public Sql_alloc
|
||||||
{
|
{
|
||||||
sp_instr(const sp_instr &); /* Prevent use of these */
|
sp_instr(const sp_instr &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr &);
|
void operator=(sp_instr &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint marked;
|
uint marked;
|
||||||
uint m_ip; // My index
|
uint m_ip; ///< My index
|
||||||
sp_pcontext *m_ctx; // My parse context
|
sp_pcontext *m_ctx; ///< My parse context
|
||||||
|
|
||||||
// Should give each a name or type code for debugging purposes?
|
/// Should give each a name or type code for debugging purposes?
|
||||||
sp_instr(uint ip, sp_pcontext *ctx)
|
sp_instr(uint ip, sp_pcontext *ctx)
|
||||||
:Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx)
|
:Query_arena(0, INITIALIZED_FOR_SP), marked(0), m_ip(ip), m_ctx(ctx)
|
||||||
{}
|
{}
|
||||||
|
|
@ -538,21 +547,19 @@ public:
|
||||||
{ free_items(); }
|
{ free_items(); }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Execute this instruction
|
Execute this instruction
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
execute()
|
@param thd Thread handle
|
||||||
thd Thread handle
|
@param[out] nextp index of the next instruction to execute. (For most
|
||||||
nextp OUT index of the next instruction to execute. (For most
|
instructions this will be the instruction following this
|
||||||
instructions this will be the instruction following this
|
one). Note that this parameter is undefined in case of
|
||||||
one). Note that this parameter is undefined in case of
|
errors, use get_cont_dest() to find the continuation
|
||||||
errors, use get_cont_dest() to find the continuation
|
instruction for CONTINUE error handlers.
|
||||||
instruction for CONTINUE error handlers.
|
|
||||||
|
@retval 0 on success,
|
||||||
RETURN
|
@retval other if some error occured
|
||||||
0 on success,
|
|
||||||
other if some error occurred
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
virtual int execute(THD *thd, uint *nextp) = 0;
|
virtual int execute(THD *thd, uint *nextp) = 0;
|
||||||
|
|
@ -590,7 +597,7 @@ public:
|
||||||
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
virtual void backpatch(uint dest, sp_pcontext *dst_ctx)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Mark this instruction as reachable during optimization and return the
|
Mark this instruction as reachable during optimization and return the
|
||||||
index to the next instruction. Jump instruction will add their
|
index to the next instruction. Jump instruction will add their
|
||||||
destination to the leads list.
|
destination to the leads list.
|
||||||
|
|
@ -601,7 +608,7 @@ public:
|
||||||
return m_ip+1;
|
return m_ip+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Short-cut jumps to jumps during optimization. This is used by the
|
Short-cut jumps to jumps during optimization. This is used by the
|
||||||
jump instructions' opt_mark() methods. 'start' is the starting point,
|
jump instructions' opt_mark() methods. 'start' is the starting point,
|
||||||
used to prevent the mark sweep from looping for ever. Return the
|
used to prevent the mark sweep from looping for ever. Return the
|
||||||
|
|
@ -612,7 +619,7 @@ public:
|
||||||
return m_ip;
|
return m_ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Inform the instruction that it has been moved during optimization.
|
Inform the instruction that it has been moved during optimization.
|
||||||
Most instructions will simply update its index, but jump instructions
|
Most instructions will simply update its index, but jump instructions
|
||||||
must also take care of their destination pointers. Forward jumps get
|
must also take care of their destination pointers. Forward jumps get
|
||||||
|
|
@ -626,7 +633,7 @@ public:
|
||||||
}; // class sp_instr : public Sql_alloc
|
}; // class sp_instr : public Sql_alloc
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Auxilary class to which instructions delegate responsibility
|
Auxilary class to which instructions delegate responsibility
|
||||||
for handling LEX and preparations before executing statement
|
for handling LEX and preparations before executing statement
|
||||||
or calculating complex expression.
|
or calculating complex expression.
|
||||||
|
|
@ -634,13 +641,14 @@ public:
|
||||||
Exist mainly to avoid having double hierarchy between instruction
|
Exist mainly to avoid having double hierarchy between instruction
|
||||||
classes.
|
classes.
|
||||||
|
|
||||||
TODO: Add ability to not store LEX and do any preparations if
|
@todo
|
||||||
expression used is simple.
|
Add ability to not store LEX and do any preparations if
|
||||||
|
expression used is simple.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class sp_lex_keeper
|
class sp_lex_keeper
|
||||||
{
|
{
|
||||||
/* Prevent use of these */
|
/** Prevent use of these */
|
||||||
sp_lex_keeper(const sp_lex_keeper &);
|
sp_lex_keeper(const sp_lex_keeper &);
|
||||||
void operator=(sp_lex_keeper &);
|
void operator=(sp_lex_keeper &);
|
||||||
public:
|
public:
|
||||||
|
|
@ -660,10 +668,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare execution of instruction using LEX, if requested check whenever
|
Prepare execution of instruction using LEX, if requested check whenever
|
||||||
we have read access to tables used and open/lock them, call instruction's
|
we have read access to tables used and open/lock them, call instruction's
|
||||||
exec_core() method, perform cleanup afterwards.
|
exec_core() method, perform cleanup afterwards.
|
||||||
|
|
||||||
|
@todo Conflicting comment in sp_head.cc
|
||||||
*/
|
*/
|
||||||
int reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables,
|
int reset_lex_and_exec_core(THD *thd, uint *nextp, bool open_tables,
|
||||||
sp_instr* instr);
|
sp_instr* instr);
|
||||||
|
|
@ -680,7 +690,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
LEX *m_lex;
|
LEX *m_lex;
|
||||||
/*
|
/**
|
||||||
Indicates whenever this sp_lex_keeper instance responsible
|
Indicates whenever this sp_lex_keeper instance responsible
|
||||||
for LEX deletion.
|
for LEX deletion.
|
||||||
*/
|
*/
|
||||||
|
|
@ -693,13 +703,13 @@ private:
|
||||||
prelocked mode itself.
|
prelocked mode itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
List of additional tables this statement needs to lock when it
|
List of additional tables this statement needs to lock when it
|
||||||
enters/leaves prelocked mode on its own.
|
enters/leaves prelocked mode on its own.
|
||||||
*/
|
*/
|
||||||
TABLE_LIST *prelocking_tables;
|
TABLE_LIST *prelocking_tables;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
The value m_lex->query_tables_own_last should be set to this when the
|
The value m_lex->query_tables_own_last should be set to this when the
|
||||||
statement enters/leaves prelocked mode on its own.
|
statement enters/leaves prelocked mode on its own.
|
||||||
*/
|
*/
|
||||||
|
|
@ -707,17 +717,17 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
/**
|
||||||
// Call out to some prepared SQL statement.
|
Call out to some prepared SQL statement.
|
||||||
//
|
*/
|
||||||
class sp_instr_stmt : public sp_instr
|
class sp_instr_stmt : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_stmt(const sp_instr_stmt &); /* Prevent use of these */
|
sp_instr_stmt(const sp_instr_stmt &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_stmt &);
|
void operator=(sp_instr_stmt &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LEX_STRING m_query; // For thd->query
|
LEX_STRING m_query; ///< For thd->query
|
||||||
|
|
||||||
sp_instr_stmt(uint ip, sp_pcontext *ctx, LEX *lex)
|
sp_instr_stmt(uint ip, sp_pcontext *ctx, LEX *lex)
|
||||||
: sp_instr(ip, ctx), m_lex_keeper(lex, TRUE)
|
: sp_instr(ip, ctx), m_lex_keeper(lex, TRUE)
|
||||||
|
|
@ -744,7 +754,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_set : public sp_instr
|
class sp_instr_set : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_set(const sp_instr_set &); /* Prevent use of these */
|
sp_instr_set(const sp_instr_set &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_set &);
|
void operator=(sp_instr_set &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -767,15 +777,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint m_offset; // Frame offset
|
uint m_offset; ///< Frame offset
|
||||||
Item *m_value;
|
Item *m_value;
|
||||||
enum enum_field_types m_type; // The declared type
|
enum enum_field_types m_type; ///< The declared type
|
||||||
sp_lex_keeper m_lex_keeper;
|
sp_lex_keeper m_lex_keeper;
|
||||||
|
|
||||||
}; // class sp_instr_set : public sp_instr
|
}; // class sp_instr_set : public sp_instr
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Set NEW/OLD row field value instruction. Used in triggers.
|
Set NEW/OLD row field value instruction. Used in triggers.
|
||||||
*/
|
*/
|
||||||
class sp_instr_set_trigger_field : public sp_instr
|
class sp_instr_set_trigger_field : public sp_instr
|
||||||
|
|
@ -809,18 +819,19 @@ private:
|
||||||
}; // class sp_instr_trigger_field : public sp_instr
|
}; // class sp_instr_trigger_field : public sp_instr
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
An abstract class for all instructions with destinations that
|
An abstract class for all instructions with destinations that
|
||||||
needs to be updated by the optimizer.
|
needs to be updated by the optimizer.
|
||||||
|
|
||||||
Even if not all subclasses will use both the normal destination and
|
Even if not all subclasses will use both the normal destination and
|
||||||
the continuation destination, we put them both here for simplicity.
|
the continuation destination, we put them both here for simplicity.
|
||||||
*/
|
*/
|
||||||
class sp_instr_opt_meta : public sp_instr
|
class sp_instr_opt_meta : public sp_instr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
uint m_dest; // Where we will go
|
uint m_dest; ///< Where we will go
|
||||||
uint m_cont_dest; // Where continue handlers will go
|
uint m_cont_dest; ///< Where continue handlers will go
|
||||||
|
|
||||||
sp_instr_opt_meta(uint ip, sp_pcontext *ctx)
|
sp_instr_opt_meta(uint ip, sp_pcontext *ctx)
|
||||||
: sp_instr(ip, ctx),
|
: sp_instr(ip, ctx),
|
||||||
|
|
@ -842,14 +853,14 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
sp_instr *m_optdest; // Used during optimization
|
sp_instr *m_optdest; ///< Used during optimization
|
||||||
sp_instr *m_cont_optdest; // Used during optimization
|
sp_instr *m_cont_optdest; ///< Used during optimization
|
||||||
|
|
||||||
}; // class sp_instr_opt_meta : public sp_instr
|
}; // class sp_instr_opt_meta : public sp_instr
|
||||||
|
|
||||||
class sp_instr_jump : public sp_instr_opt_meta
|
class sp_instr_jump : public sp_instr_opt_meta
|
||||||
{
|
{
|
||||||
sp_instr_jump(const sp_instr_jump &); /* Prevent use of these */
|
sp_instr_jump(const sp_instr_jump &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_jump &);
|
void operator=(sp_instr_jump &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -881,7 +892,7 @@ public:
|
||||||
m_dest= dest;
|
m_dest= dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update the destination; used by the optimizer.
|
Update the destination; used by the optimizer.
|
||||||
*/
|
*/
|
||||||
virtual void set_destination(uint old_dest, uint new_dest)
|
virtual void set_destination(uint old_dest, uint new_dest)
|
||||||
|
|
@ -895,7 +906,7 @@ public:
|
||||||
|
|
||||||
class sp_instr_jump_if_not : public sp_instr_jump
|
class sp_instr_jump_if_not : public sp_instr_jump
|
||||||
{
|
{
|
||||||
sp_instr_jump_if_not(const sp_instr_jump_if_not &); /* Prevent use of these */
|
sp_instr_jump_if_not(const sp_instr_jump_if_not &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_jump_if_not &);
|
void operator=(sp_instr_jump_if_not &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -921,7 +932,7 @@ public:
|
||||||
|
|
||||||
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
|
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
|
||||||
|
|
||||||
/* Override sp_instr_jump's shortcut; we stop here */
|
/** Override sp_instr_jump's shortcut; we stop here */
|
||||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||||
{
|
{
|
||||||
return m_ip;
|
return m_ip;
|
||||||
|
|
@ -938,7 +949,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Item *m_expr; // The condition
|
Item *m_expr; ///< The condition
|
||||||
sp_lex_keeper m_lex_keeper;
|
sp_lex_keeper m_lex_keeper;
|
||||||
|
|
||||||
}; // class sp_instr_jump_if_not : public sp_instr_jump
|
}; // class sp_instr_jump_if_not : public sp_instr_jump
|
||||||
|
|
@ -946,7 +957,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_freturn : public sp_instr
|
class sp_instr_freturn : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_freturn(const sp_instr_freturn &); /* Prevent use of these */
|
sp_instr_freturn(const sp_instr_freturn &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_freturn &);
|
void operator=(sp_instr_freturn &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -983,7 +994,7 @@ protected:
|
||||||
|
|
||||||
class sp_instr_hpush_jump : public sp_instr_jump
|
class sp_instr_hpush_jump : public sp_instr_jump
|
||||||
{
|
{
|
||||||
sp_instr_hpush_jump(const sp_instr_hpush_jump &); /* Prevent use of these */
|
sp_instr_hpush_jump(const sp_instr_hpush_jump &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_hpush_jump &);
|
void operator=(sp_instr_hpush_jump &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1005,7 +1016,7 @@ public:
|
||||||
|
|
||||||
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
|
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads);
|
||||||
|
|
||||||
/* Override sp_instr_jump's shortcut; we stop here. */
|
/** Override sp_instr_jump's shortcut; we stop here. */
|
||||||
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
virtual uint opt_shortcut_jump(sp_head *sp, sp_instr *start)
|
||||||
{
|
{
|
||||||
return m_ip;
|
return m_ip;
|
||||||
|
|
@ -1018,7 +1029,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int m_type; // Handler type
|
int m_type; ///< Handler type
|
||||||
uint m_frame;
|
uint m_frame;
|
||||||
List<struct sp_cond_type> m_cond;
|
List<struct sp_cond_type> m_cond;
|
||||||
|
|
||||||
|
|
@ -1027,7 +1038,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_hpop : public sp_instr
|
class sp_instr_hpop : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_hpop(const sp_instr_hpop &); /* Prevent use of these */
|
sp_instr_hpop(const sp_instr_hpop &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_hpop &);
|
void operator=(sp_instr_hpop &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1052,7 +1063,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_hreturn : public sp_instr_jump
|
class sp_instr_hreturn : public sp_instr_jump
|
||||||
{
|
{
|
||||||
sp_instr_hreturn(const sp_instr_hreturn &); /* Prevent use of these */
|
sp_instr_hreturn(const sp_instr_hreturn &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_hreturn &);
|
void operator=(sp_instr_hreturn &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1083,10 +1094,10 @@ private:
|
||||||
}; // class sp_instr_hreturn : public sp_instr_jump
|
}; // class sp_instr_hreturn : public sp_instr_jump
|
||||||
|
|
||||||
|
|
||||||
/* This is DECLARE CURSOR */
|
/** This is DECLARE CURSOR */
|
||||||
class sp_instr_cpush : public sp_instr
|
class sp_instr_cpush : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_cpush(const sp_instr_cpush &); /* Prevent use of these */
|
sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_cpush &);
|
void operator=(sp_instr_cpush &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1102,7 +1113,7 @@ public:
|
||||||
|
|
||||||
virtual void print(String *str);
|
virtual void print(String *str);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This call is used to cleanup the instruction when a sensitive
|
This call is used to cleanup the instruction when a sensitive
|
||||||
cursor is closed. For now stored procedures always use materialized
|
cursor is closed. For now stored procedures always use materialized
|
||||||
cursors and the call is not used.
|
cursors and the call is not used.
|
||||||
|
|
@ -1111,14 +1122,14 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
sp_lex_keeper m_lex_keeper;
|
sp_lex_keeper m_lex_keeper;
|
||||||
uint m_cursor; /* Frame offset (for debugging) */
|
uint m_cursor; /**< Frame offset (for debugging) */
|
||||||
|
|
||||||
}; // class sp_instr_cpush : public sp_instr
|
}; // class sp_instr_cpush : public sp_instr
|
||||||
|
|
||||||
|
|
||||||
class sp_instr_cpop : public sp_instr
|
class sp_instr_cpop : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_cpop(const sp_instr_cpop &); /* Prevent use of these */
|
sp_instr_cpop(const sp_instr_cpop &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_cpop &);
|
void operator=(sp_instr_cpop &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1143,7 +1154,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_copen : public sp_instr
|
class sp_instr_copen : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_copen(const sp_instr_copen &); /* Prevent use of these */
|
sp_instr_copen(const sp_instr_copen &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_copen &);
|
void operator=(sp_instr_copen &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1163,14 +1174,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint m_cursor; // Stack index
|
uint m_cursor; ///< Stack index
|
||||||
|
|
||||||
}; // class sp_instr_copen : public sp_instr_stmt
|
}; // class sp_instr_copen : public sp_instr_stmt
|
||||||
|
|
||||||
|
|
||||||
class sp_instr_cclose : public sp_instr
|
class sp_instr_cclose : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_cclose(const sp_instr_cclose &); /* Prevent use of these */
|
sp_instr_cclose(const sp_instr_cclose &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_cclose &);
|
void operator=(sp_instr_cclose &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1195,7 +1206,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_cfetch : public sp_instr
|
class sp_instr_cfetch : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_cfetch(const sp_instr_cfetch &); /* Prevent use of these */
|
sp_instr_cfetch(const sp_instr_cfetch &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_cfetch &);
|
void operator=(sp_instr_cfetch &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -1228,7 +1239,7 @@ private:
|
||||||
|
|
||||||
class sp_instr_error : public sp_instr
|
class sp_instr_error : public sp_instr
|
||||||
{
|
{
|
||||||
sp_instr_error(const sp_instr_error &); /* Prevent use of these */
|
sp_instr_error(const sp_instr_error &); /**< Prevent use of these */
|
||||||
void operator=(sp_instr_error &);
|
void operator=(sp_instr_error &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -1982,7 +1982,7 @@ static void relink_unused(TABLE *table)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Prepare an open merge table for close.
|
Prepare an open merge table for close.
|
||||||
|
|
||||||
@param[in] thd thread context
|
@param[in] thd thread context
|
||||||
@param[in] table table to prepare
|
@param[in] table table to prepare
|
||||||
|
|
@ -2053,8 +2053,8 @@ static void unlink_open_merge(THD *thd, TABLE *table, TABLE ***prev_pp)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Remove all instances of table from thread's open list and
|
Remove all instances of table from thread's open list and
|
||||||
table cache.
|
table cache.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param find Table to remove
|
@param find Table to remove
|
||||||
|
|
@ -2117,7 +2117,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Auxiliary routine which closes and drops open table.
|
Auxiliary routine which closes and drops open table.
|
||||||
|
|
||||||
@param thd Thread handle
|
@param thd Thread handle
|
||||||
@param table TABLE object for table to be dropped
|
@param table TABLE object for table to be dropped
|
||||||
|
|
@ -2324,9 +2324,9 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Create and insert into table cache placeholder for table
|
Create and insert into table cache placeholder for table
|
||||||
which will prevent its opening (or creation) (a.k.a lock
|
which will prevent its opening (or creation) (a.k.a lock
|
||||||
table name).
|
table name).
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param key Table cache key for name to be locked
|
@param key Table cache key for name to be locked
|
||||||
|
|
@ -2375,8 +2375,8 @@ TABLE *table_cache_insert_placeholder(THD *thd, const char *key,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Obtain an exclusive name lock on the table if it is not cached
|
Obtain an exclusive name lock on the table if it is not cached
|
||||||
in the table cache.
|
in the table cache.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param db Name of database
|
@param db Name of database
|
||||||
|
|
@ -2427,8 +2427,8 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Check that table exists in table definition cache, on disk
|
Check that table exists in table definition cache, on disk
|
||||||
or in some storage engine.
|
or in some storage engine.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param table Table list element
|
@param table Table list element
|
||||||
|
|
@ -3142,8 +3142,8 @@ bool reopen_table(TABLE *table)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Close all instances of a table open by this thread and replace
|
Close all instances of a table open by this thread and replace
|
||||||
them with exclusive name-locks.
|
them with exclusive name-locks.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param db Database name for the table to be closed
|
@param db Database name for the table to be closed
|
||||||
|
|
@ -3212,7 +3212,7 @@ void close_data_files_and_morph_locks(THD *thd, const char *db,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Reattach MERGE children after reopen.
|
Reattach MERGE children after reopen.
|
||||||
|
|
||||||
@param[in] thd thread context
|
@param[in] thd thread context
|
||||||
@param[in,out] err_tables_p pointer to pointer of tables in error
|
@param[in,out] err_tables_p pointer to pointer of tables in error
|
||||||
|
|
@ -3268,7 +3268,7 @@ static bool reattach_merge(THD *thd, TABLE **err_tables_p)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Reopen all tables with closed data files.
|
Reopen all tables with closed data files.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param get_locks Should we get locks after reopening tables ?
|
@param get_locks Should we get locks after reopening tables ?
|
||||||
|
|
@ -3412,8 +3412,8 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Close handlers for tables in list, but leave the TABLE structure
|
Close handlers for tables in list, but leave the TABLE structure
|
||||||
intact so that we can re-open these quickly.
|
intact so that we can re-open these quickly.
|
||||||
|
|
||||||
@param thd Thread context
|
@param thd Thread context
|
||||||
@param table Head of the list of TABLE objects
|
@param table Head of the list of TABLE objects
|
||||||
|
|
|
||||||
|
|
@ -1524,7 +1524,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Synchronize the thread with any flushing operations.
|
Synchronize the thread with any flushing operations.
|
||||||
|
|
||||||
This helper function is called whenever a thread needs to operate on the
|
This helper function is called whenever a thread needs to operate on the
|
||||||
query cache structure (example: during invalidation). If a table flush is in
|
query cache structure (example: during invalidation). If a table flush is in
|
||||||
|
|
@ -1565,7 +1565,7 @@ void Query_cache::wait_while_table_flush_is_in_progress(bool *interrupt)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Remove all cached queries that uses the given database
|
Remove all cached queries that uses the given database.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Query_cache::invalidate(char *db)
|
void Query_cache::invalidate(char *db)
|
||||||
|
|
@ -1675,8 +1675,8 @@ void Query_cache::flush()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Rearrange the memory blocks and join result in cache in 1 block (if
|
Rearrange the memory blocks and join result in cache in 1 block (if
|
||||||
result length > join_limit)
|
result length > join_limit)
|
||||||
|
|
||||||
@param[in] join_limit If the minimum length of a result block to be joined.
|
@param[in] join_limit If the minimum length of a result block to be joined.
|
||||||
@param[in] iteration_limit The maximum number of packing and joining
|
@param[in] iteration_limit The maximum number of packing and joining
|
||||||
|
|
@ -1946,7 +1946,7 @@ void Query_cache::make_disabled()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class Query_cache
|
@class Query_cache
|
||||||
@brief Free all resources allocated by the cache.
|
Free all resources allocated by the cache.
|
||||||
|
|
||||||
This function frees all resources allocated by the cache. You
|
This function frees all resources allocated by the cache. You
|
||||||
have to call init_cache() before using the cache again. This function
|
have to call init_cache() before using the cache again. This function
|
||||||
|
|
@ -1970,7 +1970,7 @@ void Query_cache::free_cache()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Flush the cache.
|
Flush the cache.
|
||||||
|
|
||||||
This function will flush cache contents. It assumes we have
|
This function will flush cache contents. It assumes we have
|
||||||
'structure_guard_mutex' locked. The function sets the m_cache_status flag and
|
'structure_guard_mutex' locked. The function sets the m_cache_status flag and
|
||||||
|
|
@ -2516,7 +2516,7 @@ Query_cache::invalidate_table_internal(THD *thd, uchar *key, uint32 key_length)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Invalidate a linked list of query cache blocks.
|
Invalidate a linked list of query cache blocks.
|
||||||
|
|
||||||
Each block tries to aquire a block level lock before
|
Each block tries to aquire a block level lock before
|
||||||
free_query is a called. This function will in turn affect
|
free_query is a called. This function will in turn affect
|
||||||
|
|
@ -2684,7 +2684,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Insert used table name into the cache.
|
Insert used table name into the cache.
|
||||||
|
|
||||||
@return Error status
|
@return Error status
|
||||||
@retval FALSE On error
|
@retval FALSE On error
|
||||||
|
|
@ -3413,8 +3413,8 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Rearrange all memory blocks so that free memory joins at the
|
Rearrange all memory blocks so that free memory joins at the
|
||||||
'bottom' of the allocated memory block containing all cache data.
|
'bottom' of the allocated memory block containing all cache data.
|
||||||
@see Query_cache::pack(ulong join_limit, uint iteration_limit)
|
@see Query_cache::pack(ulong join_limit, uint iteration_limit)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -4028,7 +4028,7 @@ void Query_cache::tables_dump()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Checks integrity of the various linked lists
|
Checks integrity of the various linked lists
|
||||||
|
|
||||||
@return Error status code
|
@return Error status code
|
||||||
@retval FALSE Query cache is operational.
|
@retval FALSE Query cache is operational.
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,8 @@ struct Query_cache_result;
|
||||||
class Query_cache;
|
class Query_cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief This class represents a node in the linked chain of queries
|
This class represents a node in the linked chain of queries
|
||||||
belonging to one table.
|
belonging to one table.
|
||||||
|
|
||||||
@note The root of this linked list is not a query-type block, but the table-
|
@note The root of this linked list is not a query-type block, but the table-
|
||||||
type block which all queries has in common.
|
type block which all queries has in common.
|
||||||
|
|
|
||||||
|
|
@ -952,7 +952,7 @@ void THD::cleanup_after_query()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a LEX_STRING in this connection
|
Create a LEX_STRING in this connection.
|
||||||
|
|
||||||
@param lex_str pointer to LEX_STRING object to be initialized
|
@param lex_str pointer to LEX_STRING object to be initialized
|
||||||
@param str initializer to be copied into lex_str
|
@param str initializer to be copied into lex_str
|
||||||
|
|
|
||||||
|
|
@ -77,10 +77,10 @@ typedef struct st_user_var_events
|
||||||
was actually changed or not.
|
was actually changed or not.
|
||||||
*/
|
*/
|
||||||
typedef struct st_copy_info {
|
typedef struct st_copy_info {
|
||||||
ha_rows records; /* Number of processed records */
|
ha_rows records; /**< Number of processed records */
|
||||||
ha_rows deleted; /* Number of deleted records */
|
ha_rows deleted; /**< Number of deleted records */
|
||||||
ha_rows updated; /* Number of updated records */
|
ha_rows updated; /**< Number of updated records */
|
||||||
ha_rows copied; /* Number of copied records */
|
ha_rows copied; /**< Number of copied records */
|
||||||
ha_rows error_count;
|
ha_rows error_count;
|
||||||
ha_rows touched; /* Number of touched records */
|
ha_rows touched; /* Number of touched records */
|
||||||
enum enum_duplicates handle_duplicates;
|
enum enum_duplicates handle_duplicates;
|
||||||
|
|
@ -1046,14 +1046,17 @@ public:
|
||||||
*/
|
*/
|
||||||
char *catalog;
|
char *catalog;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
WARNING: some members of THD (currently 'Statement::db',
|
@note
|
||||||
|
Some members of THD (currently 'Statement::db',
|
||||||
'catalog' and 'query') are set and alloced by the slave SQL thread
|
'catalog' and 'query') are set and alloced by the slave SQL thread
|
||||||
(for the THD of that thread); that thread is (and must remain, for now)
|
(for the THD of that thread); that thread is (and must remain, for now)
|
||||||
the only responsible for freeing these 3 members. If you add members
|
the only responsible for freeing these 3 members. If you add members
|
||||||
here, and you add code to set them in replication, don't forget to
|
here, and you add code to set them in replication, don't forget to
|
||||||
free_them_and_set_them_to_0 in replication properly. For details see
|
free_them_and_set_them_to_0 in replication properly. For details see
|
||||||
the 'err:' label of the handle_slave_sql() in sql/slave.cc.
|
the 'err:' label of the handle_slave_sql() in sql/slave.cc.
|
||||||
|
|
||||||
|
@see handle_slave_sql
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Security_context main_security_ctx;
|
Security_context main_security_ctx;
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
Declarations.
|
Declarations.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Sensitive_cursor -- a sensitive non-materialized server side
|
Sensitive_cursor -- a sensitive non-materialized server side
|
||||||
cursor An instance of this class cursor has its own runtime
|
cursor. An instance of this class cursor has its own runtime
|
||||||
state -- list of used items and memory root for runtime memory,
|
state -- list of used items and memory root for runtime memory,
|
||||||
open and locked tables, change list for the changes of the
|
open and locked tables, change list for the changes of the
|
||||||
parsed tree. This state is freed when the cursor is closed.
|
parsed tree. This state is freed when the cursor is closed.
|
||||||
|
|
@ -69,7 +69,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Materialized_cursor -- an insensitive materialized server-side
|
Materialized_cursor -- an insensitive materialized server-side
|
||||||
cursor. The result set of this cursor is saved in a temporary
|
cursor. The result set of this cursor is saved in a temporary
|
||||||
table at open. The cursor itself is simply an interface for the
|
table at open. The cursor itself is simply an interface for the
|
||||||
|
|
@ -96,7 +96,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Select_materialize -- a mediator between a cursor query and the
|
Select_materialize -- a mediator between a cursor query and the
|
||||||
protocol. In case we were not able to open a non-materialzed
|
protocol. In case we were not able to open a non-materialzed
|
||||||
cursor, it creates an internal temporary HEAP table, and insert
|
cursor, it creates an internal temporary HEAP table, and insert
|
||||||
|
|
@ -107,7 +107,7 @@ public:
|
||||||
|
|
||||||
class Select_materialize: public select_union
|
class Select_materialize: public select_union
|
||||||
{
|
{
|
||||||
select_result *result; /* the result object of the caller (PS or SP) */
|
select_result *result; /**< the result object of the caller (PS or SP) */
|
||||||
public:
|
public:
|
||||||
Select_materialize(select_result *result_arg) :result(result_arg) {}
|
Select_materialize(select_result *result_arg) :result(result_arg) {}
|
||||||
virtual bool send_fields(List<Item> &list, uint flags);
|
virtual bool send_fields(List<Item> &list, uint flags);
|
||||||
|
|
@ -116,22 +116,21 @@ public:
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Attempt to open a materialized or non-materialized cursor.
|
Attempt to open a materialized or non-materialized cursor.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd thread handle
|
||||||
mysql_open_cursor()
|
@param[in] flags create a materialized cursor or not
|
||||||
thd thread handle
|
@param[in] result result class of the caller used as a destination
|
||||||
flags [in] create a materialized cursor or not
|
for the rows fetched from the cursor
|
||||||
result [in] result class of the caller used as a destination
|
@param[out] pcursor a pointer to store a pointer to cursor in
|
||||||
for the rows fetched from the cursor
|
|
||||||
pcursor [out] a pointer to store a pointer to cursor in
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 the query has been successfully executed; in this
|
0 the query has been successfully executed; in this
|
||||||
case pcursor may or may not contain
|
case pcursor may or may not contain
|
||||||
a pointer to an open cursor.
|
a pointer to an open cursor.
|
||||||
non-zero an error, 'pcursor' has been left intact.
|
@retval
|
||||||
|
non-zero an error, 'pcursor' has been left intact.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int mysql_open_cursor(THD *thd, uint flags, select_result *result,
|
int mysql_open_cursor(THD *thd, uint flags, select_result *result,
|
||||||
|
|
@ -279,6 +278,14 @@ Sensitive_cursor::Sensitive_cursor(THD *thd, select_result *result_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Save THD state into cursor.
|
||||||
|
|
||||||
|
@todo
|
||||||
|
- XXX: thd->locked_tables is not changed.
|
||||||
|
- What problems can we have with it if cursor is open?
|
||||||
|
- TODO: must be fixed because of the prelocked mode.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Sensitive_cursor::post_open(THD *thd)
|
Sensitive_cursor::post_open(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -334,6 +341,10 @@ Sensitive_cursor::post_open(THD *thd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
bzero cursor state in THD.
|
||||||
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
Sensitive_cursor::reset_thd(THD *thd)
|
Sensitive_cursor::reset_thd(THD *thd)
|
||||||
{
|
{
|
||||||
|
|
@ -393,20 +404,13 @@ Sensitive_cursor::open(JOIN *join_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
SYNOPSIS
|
Fetch next num_rows rows from the cursor and send them to the client.
|
||||||
Sensitive_cursor::fetch()
|
|
||||||
num_rows fetch up to this number of rows (maybe less)
|
|
||||||
|
|
||||||
DESCRIPTION
|
Precondition:
|
||||||
Fetch next num_rows rows from the cursor and send them to the client
|
- Sensitive_cursor is open
|
||||||
|
|
||||||
Precondition:
|
@param num_rows fetch up to this number of rows (maybe less)
|
||||||
Sensitive_cursor is open
|
|
||||||
|
|
||||||
RETURN VALUES:
|
|
||||||
none, this function will send OK to the clinet or set an error
|
|
||||||
message in THD
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -478,6 +482,11 @@ Sensitive_cursor::fetch(ulong num_rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
@todo
|
||||||
|
Another hack: we need to set THD state as if in a fetch to be
|
||||||
|
able to call stmt close.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Sensitive_cursor::close()
|
Sensitive_cursor::close()
|
||||||
{
|
{
|
||||||
|
|
@ -579,10 +588,9 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Fetch up to the given number of rows from a materialized cursor.
|
Fetch up to the given number of rows from a materialized cursor.
|
||||||
|
|
||||||
DESCRIPTION
|
|
||||||
Precondition: the cursor is open.
|
Precondition: the cursor is open.
|
||||||
|
|
||||||
If the cursor points after the last row, the fetch will automatically
|
If the cursor points after the last row, the fetch will automatically
|
||||||
|
|
@ -590,10 +598,6 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused)))
|
||||||
with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
|
with SERVER_STATUS_LAST_ROW_SENT). This is an extra round trip
|
||||||
and probably should be improved to return
|
and probably should be improved to return
|
||||||
SERVER_STATUS_LAST_ROW_SENT along with the last row.
|
SERVER_STATUS_LAST_ROW_SENT along with the last row.
|
||||||
|
|
||||||
RETURN VALUE
|
|
||||||
none, in case of success the row is sent to the client, otherwise
|
|
||||||
an error message is set in THD
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Materialized_cursor::fetch(ulong num_rows)
|
void Materialized_cursor::fetch(ulong num_rows)
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,14 @@
|
||||||
#pragma interface /* gcc class interface */
|
#pragma interface /* gcc class interface */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
Declarations for implementation of server side cursors. Only
|
Declarations for implementation of server side cursors. Only
|
||||||
read-only non-scrollable cursors are currently implemented.
|
read-only non-scrollable cursors are currently implemented.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Server_side_cursor -- an interface for materialized and
|
Server_side_cursor -- an interface for materialized and
|
||||||
sensitive (non-materialized) implementation of cursors. All
|
sensitive (non-materialized) implementation of cursors. All
|
||||||
cursors are self-contained (created in their own memory root).
|
cursors are self-contained (created in their own memory root).
|
||||||
|
|
@ -36,7 +38,7 @@
|
||||||
class Server_side_cursor: protected Query_arena, public Sql_alloc
|
class Server_side_cursor: protected Query_arena, public Sql_alloc
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
/* Row destination used for fetch */
|
/** Row destination used for fetch */
|
||||||
select_result *result;
|
select_result *result;
|
||||||
public:
|
public:
|
||||||
Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg)
|
Server_side_cursor(MEM_ROOT *mem_root_arg, select_result *result_arg)
|
||||||
|
|
@ -58,8 +60,7 @@ int mysql_open_cursor(THD *thd, uint flags,
|
||||||
select_result *result,
|
select_result *result,
|
||||||
Server_side_cursor **res);
|
Server_side_cursor **res);
|
||||||
|
|
||||||
/* Possible values for flags */
|
/** Possible values for flags */
|
||||||
|
|
||||||
enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 };
|
enum { ANY_CURSOR= 1, ALWAYS_MATERIALIZED_CURSOR= 2 };
|
||||||
|
|
||||||
#endif /* _sql_cusor_h_ */
|
#endif /* _sql_cusor_h_ */
|
||||||
|
|
|
||||||
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 */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/* classes to use when handling where clause */
|
/**
|
||||||
|
@file
|
||||||
|
|
||||||
|
@brief
|
||||||
|
classes to use when handling where clause
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef USE_PRAGMA_INTERFACE
|
#ifdef USE_PRAGMA_INTERFACE
|
||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
|
|
@ -25,12 +30,12 @@
|
||||||
|
|
||||||
typedef struct keyuse_t {
|
typedef struct keyuse_t {
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
Item *val; /* or value if no field */
|
Item *val; /**< or value if no field */
|
||||||
table_map used_tables;
|
table_map used_tables;
|
||||||
uint key, keypart, optimize;
|
uint key, keypart, optimize;
|
||||||
key_part_map keypart_map;
|
key_part_map keypart_map;
|
||||||
ha_rows ref_table_rows;
|
ha_rows ref_table_rows;
|
||||||
/*
|
/**
|
||||||
If true, the comparison this value was created from will not be
|
If true, the comparison this value was created from will not be
|
||||||
satisfied if val has NULL 'value'.
|
satisfied if val has NULL 'value'.
|
||||||
*/
|
*/
|
||||||
|
|
@ -53,13 +58,13 @@ class store_key;
|
||||||
typedef struct st_table_ref
|
typedef struct st_table_ref
|
||||||
{
|
{
|
||||||
bool key_err;
|
bool key_err;
|
||||||
uint key_parts; // num of ...
|
uint key_parts; ///< num of ...
|
||||||
uint key_length; // length of key_buff
|
uint key_length; ///< length of key_buff
|
||||||
int key; // key no
|
int key; ///< key no
|
||||||
uchar *key_buff; // value to look for with key
|
uchar *key_buff; ///< value to look for with key
|
||||||
uchar *key_buff2; // key_buff+key_length
|
uchar *key_buff2; ///< key_buff+key_length
|
||||||
store_key **key_copy; //
|
store_key **key_copy; //
|
||||||
Item **items; // val()'s for each keypart
|
Item **items; ///< val()'s for each keypart
|
||||||
/*
|
/*
|
||||||
Array of pointers to trigger variables. Some/all of the pointers may be
|
Array of pointers to trigger variables. Some/all of the pointers may be
|
||||||
NULL. The ref access can be used iff
|
NULL. The ref access can be used iff
|
||||||
|
|
@ -72,18 +77,18 @@ typedef struct st_table_ref
|
||||||
underlying conditions is switched off (see subquery code for more details)
|
underlying conditions is switched off (see subquery code for more details)
|
||||||
*/
|
*/
|
||||||
bool **cond_guards;
|
bool **cond_guards;
|
||||||
/*
|
/**
|
||||||
(null_rejecting & (1<<i)) means the condition is '=' and no matching
|
(null_rejecting & (1<<i)) means the condition is '=' and no matching
|
||||||
rows will be produced if items[i] IS NULL (see add_not_null_conds())
|
rows will be produced if items[i] IS NULL (see add_not_null_conds())
|
||||||
*/
|
*/
|
||||||
key_part_map null_rejecting;
|
key_part_map null_rejecting;
|
||||||
table_map depend_map; // Table depends on these tables.
|
table_map depend_map; ///< Table depends on these tables.
|
||||||
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
|
/* null byte position in the key_buf. Used for REF_OR_NULL optimization */
|
||||||
uchar *null_ref_key;
|
uchar *null_ref_key;
|
||||||
} TABLE_REF;
|
} TABLE_REF;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
|
CACHE_FIELD and JOIN_CACHE is used on full join to cache records in outer
|
||||||
table
|
table
|
||||||
*/
|
*/
|
||||||
|
|
@ -136,18 +141,18 @@ Next_select_func setup_end_select_func(JOIN *join);
|
||||||
typedef struct st_join_table {
|
typedef struct st_join_table {
|
||||||
st_join_table() {} /* Remove gcc warning */
|
st_join_table() {} /* Remove gcc warning */
|
||||||
TABLE *table;
|
TABLE *table;
|
||||||
KEYUSE *keyuse; /* pointer to first used key */
|
KEYUSE *keyuse; /**< pointer to first used key */
|
||||||
SQL_SELECT *select;
|
SQL_SELECT *select;
|
||||||
COND *select_cond;
|
COND *select_cond;
|
||||||
QUICK_SELECT_I *quick;
|
QUICK_SELECT_I *quick;
|
||||||
Item **on_expr_ref; /* pointer to the associated on expression */
|
Item **on_expr_ref; /**< pointer to the associated on expression */
|
||||||
COND_EQUAL *cond_equal; /* multiple equalities for the on expression */
|
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
|
||||||
st_join_table *first_inner; /* first inner table for including outerjoin */
|
st_join_table *first_inner; /**< first inner table for including outerjoin */
|
||||||
bool found; /* true after all matches or null complement */
|
bool found; /**< true after all matches or null complement */
|
||||||
bool not_null_compl;/* true before null complement is added */
|
bool not_null_compl;/**< true before null complement is added */
|
||||||
st_join_table *last_inner; /* last table table for embedding outer join */
|
st_join_table *last_inner; /**< last table table for embedding outer join */
|
||||||
st_join_table *first_upper; /* first inner table for embedding outer join */
|
st_join_table *first_upper; /**< first inner table for embedding outer join */
|
||||||
st_join_table *first_unmatched; /* used for optimization purposes only */
|
st_join_table *first_unmatched; /**< used for optimization purposes only */
|
||||||
|
|
||||||
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
||||||
const char *info;
|
const char *info;
|
||||||
|
|
@ -168,10 +173,10 @@ typedef struct st_join_table {
|
||||||
Read_record_func save_read_first_record;/* to save read_first_record */
|
Read_record_func save_read_first_record;/* to save read_first_record */
|
||||||
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
|
int (*save_read_record) (READ_RECORD *);/* to save read_record.read_record */
|
||||||
double worst_seeks;
|
double worst_seeks;
|
||||||
key_map const_keys; /* Keys with constant part */
|
key_map const_keys; /**< Keys with constant part */
|
||||||
key_map checked_keys; /* Keys checked in find_best */
|
key_map checked_keys; /**< Keys checked in find_best */
|
||||||
key_map needed_reg;
|
key_map needed_reg;
|
||||||
key_map keys; /* all keys with can be used */
|
key_map keys; /**< all keys with can be used */
|
||||||
|
|
||||||
/* Either #rows in the table or 1 for const table. */
|
/* Either #rows in the table or 1 for const table. */
|
||||||
ha_rows records;
|
ha_rows records;
|
||||||
|
|
@ -189,7 +194,7 @@ typedef struct st_join_table {
|
||||||
|
|
||||||
table_map dependent,key_dependent;
|
table_map dependent,key_dependent;
|
||||||
uint use_quick,index;
|
uint use_quick,index;
|
||||||
uint status; // Save status for cache
|
uint status; ///< Save status for cache
|
||||||
uint used_fields,used_fieldlength,used_blobs;
|
uint used_fields,used_fieldlength,used_blobs;
|
||||||
enum join_type type;
|
enum join_type type;
|
||||||
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
|
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
|
||||||
|
|
@ -203,7 +208,7 @@ typedef struct st_join_table {
|
||||||
TABLE_REF ref;
|
TABLE_REF ref;
|
||||||
JOIN_CACHE cache;
|
JOIN_CACHE cache;
|
||||||
JOIN *join;
|
JOIN *join;
|
||||||
/* Bitmap of nested joins this table is part of */
|
/** Bitmap of nested joins this table is part of */
|
||||||
nested_join_map embedding_map;
|
nested_join_map embedding_map;
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
@ -220,7 +225,7 @@ enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
|
||||||
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
|
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
|
||||||
end_of_records);
|
end_of_records);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Information about a position of table within a join order. Used in join
|
Information about a position of table within a join order. Used in join
|
||||||
optimization.
|
optimization.
|
||||||
*/
|
*/
|
||||||
|
|
@ -264,25 +269,25 @@ typedef struct st_rollup
|
||||||
|
|
||||||
class JOIN :public Sql_alloc
|
class JOIN :public Sql_alloc
|
||||||
{
|
{
|
||||||
JOIN(const JOIN &rhs); /* not implemented */
|
JOIN(const JOIN &rhs); /**< not implemented */
|
||||||
JOIN& operator=(const JOIN &rhs); /* not implemented */
|
JOIN& operator=(const JOIN &rhs); /**< not implemented */
|
||||||
public:
|
public:
|
||||||
JOIN_TAB *join_tab,**best_ref;
|
JOIN_TAB *join_tab,**best_ref;
|
||||||
JOIN_TAB **map2table; // mapping between table indexes and JOIN_TABs
|
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
||||||
JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution
|
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
||||||
TABLE **table,**all_tables,*sort_by_table;
|
TABLE **table,**all_tables,*sort_by_table;
|
||||||
uint tables,const_tables;
|
uint tables,const_tables;
|
||||||
uint send_group_parts;
|
uint send_group_parts;
|
||||||
bool sort_and_group,first_record,full_join,group, no_field_update;
|
bool sort_and_group,first_record,full_join,group, no_field_update;
|
||||||
bool do_send_rows;
|
bool do_send_rows;
|
||||||
/*
|
/**
|
||||||
TRUE when we want to resume nested loop iterations when
|
TRUE when we want to resume nested loop iterations when
|
||||||
fetching data from a cursor
|
fetching data from a cursor
|
||||||
*/
|
*/
|
||||||
bool resume_nested_loop;
|
bool resume_nested_loop;
|
||||||
table_map const_table_map,found_const_table_map,outer_join;
|
table_map const_table_map,found_const_table_map,outer_join;
|
||||||
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
||||||
/*
|
/**
|
||||||
Used to fetch no more than given amount of rows per one
|
Used to fetch no more than given amount of rows per one
|
||||||
fetch operation of server side cursor.
|
fetch operation of server side cursor.
|
||||||
The value is checked in end_send and end_send_group in fashion, similar
|
The value is checked in end_send and end_send_group in fashion, similar
|
||||||
|
|
@ -294,7 +299,7 @@ public:
|
||||||
ha_rows fetch_limit;
|
ha_rows fetch_limit;
|
||||||
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
|
POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1];
|
||||||
|
|
||||||
/*
|
/* *
|
||||||
Bitmap of nested joins embedding the position at the end of the current
|
Bitmap of nested joins embedding the position at the end of the current
|
||||||
partial join (valid only during join optimizer run).
|
partial join (valid only during join optimizer run).
|
||||||
*/
|
*/
|
||||||
|
|
@ -304,25 +309,25 @@ public:
|
||||||
List<Item> *fields;
|
List<Item> *fields;
|
||||||
List<Cached_item> group_fields, group_fields_cache;
|
List<Cached_item> group_fields, group_fields_cache;
|
||||||
TABLE *tmp_table;
|
TABLE *tmp_table;
|
||||||
// used to store 2 possible tmp table of SELECT
|
/// used to store 2 possible tmp table of SELECT
|
||||||
TABLE *exec_tmp_table1, *exec_tmp_table2;
|
TABLE *exec_tmp_table1, *exec_tmp_table2;
|
||||||
THD *thd;
|
THD *thd;
|
||||||
Item_sum **sum_funcs, ***sum_funcs_end;
|
Item_sum **sum_funcs, ***sum_funcs_end;
|
||||||
/* second copy of sumfuncs (for queries with 2 temporary tables */
|
/** second copy of sumfuncs (for queries with 2 temporary tables */
|
||||||
Item_sum **sum_funcs2, ***sum_funcs_end2;
|
Item_sum **sum_funcs2, ***sum_funcs_end2;
|
||||||
Procedure *procedure;
|
Procedure *procedure;
|
||||||
Item *having;
|
Item *having;
|
||||||
Item *tmp_having; // To store having when processed temporary table
|
Item *tmp_having; ///< To store having when processed temporary table
|
||||||
Item *having_history; // Store having for explain
|
Item *having_history; ///< Store having for explain
|
||||||
ulonglong select_options;
|
ulonglong select_options;
|
||||||
select_result *result;
|
select_result *result;
|
||||||
TMP_TABLE_PARAM tmp_table_param;
|
TMP_TABLE_PARAM tmp_table_param;
|
||||||
MYSQL_LOCK *lock;
|
MYSQL_LOCK *lock;
|
||||||
// unit structure (with global parameters) for this select
|
/// unit structure (with global parameters) for this select
|
||||||
SELECT_LEX_UNIT *unit;
|
SELECT_LEX_UNIT *unit;
|
||||||
// select that processed
|
/// select that processed
|
||||||
SELECT_LEX *select_lex;
|
SELECT_LEX *select_lex;
|
||||||
/*
|
/**
|
||||||
TRUE <=> optimizer must not mark any table as a constant table.
|
TRUE <=> optimizer must not mark any table as a constant table.
|
||||||
This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
|
This is needed for subqueries in form "a IN (SELECT .. UNION SELECT ..):
|
||||||
when we optimize the select that reads the results of the union from a
|
when we optimize the select that reads the results of the union from a
|
||||||
|
|
@ -331,11 +336,11 @@ public:
|
||||||
*/
|
*/
|
||||||
bool no_const_tables;
|
bool no_const_tables;
|
||||||
|
|
||||||
JOIN *tmp_join; // copy of this JOIN to be used with temporary tables
|
JOIN *tmp_join; ///< copy of this JOIN to be used with temporary tables
|
||||||
ROLLUP rollup; // Used with rollup
|
ROLLUP rollup; ///< Used with rollup
|
||||||
|
|
||||||
bool select_distinct; // Set if SELECT DISTINCT
|
bool select_distinct; ///< Set if SELECT DISTINCT
|
||||||
/*
|
/**
|
||||||
If we have the GROUP BY statement in the query,
|
If we have the GROUP BY statement in the query,
|
||||||
but the group_list was emptied by optimizer, this
|
but the group_list was emptied by optimizer, this
|
||||||
flag is TRUE.
|
flag is TRUE.
|
||||||
|
|
@ -350,42 +355,42 @@ public:
|
||||||
It's also set if ORDER/GROUP BY is empty.
|
It's also set if ORDER/GROUP BY is empty.
|
||||||
*/
|
*/
|
||||||
bool simple_order, simple_group;
|
bool simple_order, simple_group;
|
||||||
/*
|
/**
|
||||||
Is set only in case if we have a GROUP BY clause
|
Is set only in case if we have a GROUP BY clause
|
||||||
and no ORDER BY after constant elimination of 'order'.
|
and no ORDER BY after constant elimination of 'order'.
|
||||||
*/
|
*/
|
||||||
bool no_order;
|
bool no_order;
|
||||||
/* Is set if we have a GROUP BY and we have ORDER BY on a constant. */
|
/** Is set if we have a GROUP BY and we have ORDER BY on a constant. */
|
||||||
bool skip_sort_order;
|
bool skip_sort_order;
|
||||||
|
|
||||||
bool need_tmp, hidden_group_fields;
|
bool need_tmp, hidden_group_fields;
|
||||||
DYNAMIC_ARRAY keyuse;
|
DYNAMIC_ARRAY keyuse;
|
||||||
Item::cond_result cond_value, having_value;
|
Item::cond_result cond_value, having_value;
|
||||||
List<Item> all_fields; // to store all fields that used in query
|
List<Item> all_fields; ///< to store all fields that used in query
|
||||||
//Above list changed to use temporary table
|
///Above list changed to use temporary table
|
||||||
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
|
List<Item> tmp_all_fields1, tmp_all_fields2, tmp_all_fields3;
|
||||||
//Part, shared with list above, emulate following list
|
///Part, shared with list above, emulate following list
|
||||||
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
|
List<Item> tmp_fields_list1, tmp_fields_list2, tmp_fields_list3;
|
||||||
List<Item> &fields_list; // hold field list passed to mysql_select
|
List<Item> &fields_list; ///< hold field list passed to mysql_select
|
||||||
List<Item> procedure_fields_list;
|
List<Item> procedure_fields_list;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
|
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
|
||||||
COND *conds; // ---"---
|
COND *conds; // ---"---
|
||||||
Item *conds_history; // store WHERE for explain
|
Item *conds_history; // store WHERE for explain
|
||||||
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select
|
TABLE_LIST *tables_list; ///<hold 'tables' parameter of mysql_select
|
||||||
List<TABLE_LIST> *join_list; // list of joined tables in reverse order
|
List<TABLE_LIST> *join_list; ///< list of joined tables in reverse order
|
||||||
COND_EQUAL *cond_equal;
|
COND_EQUAL *cond_equal;
|
||||||
SQL_SELECT *select; //created in optimisation phase
|
SQL_SELECT *select; ///<created in optimisation phase
|
||||||
JOIN_TAB *return_tab; //used only for outer joins
|
JOIN_TAB *return_tab; ///<used only for outer joins
|
||||||
Item **ref_pointer_array; //used pointer reference for this select
|
Item **ref_pointer_array; ///<used pointer reference for this select
|
||||||
// Copy of above to be used with different lists
|
// Copy of above to be used with different lists
|
||||||
Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
|
Item **items0, **items1, **items2, **items3, **current_ref_pointer_array;
|
||||||
uint ref_pointer_array_size; // size of above in bytes
|
uint ref_pointer_array_size; ///< size of above in bytes
|
||||||
const char *zero_result_cause; // not 0 if exec must return zero result
|
const char *zero_result_cause; ///< not 0 if exec must return zero result
|
||||||
|
|
||||||
bool union_part; // this subselect is part of union
|
bool union_part; ///< this subselect is part of union
|
||||||
bool optimized; // flag to avoid double optimization in EXPLAIN
|
bool optimized; ///< flag to avoid double optimization in EXPLAIN
|
||||||
|
|
||||||
/*
|
/*
|
||||||
storage for caching buffers allocated during query execution.
|
storage for caching buffers allocated during query execution.
|
||||||
|
|
@ -494,14 +499,14 @@ public:
|
||||||
int rollup_send_data(uint idx);
|
int rollup_send_data(uint idx);
|
||||||
int rollup_write_data(uint idx, TABLE *table);
|
int rollup_write_data(uint idx, TABLE *table);
|
||||||
void remove_subq_pushed_predicates(Item **where);
|
void remove_subq_pushed_predicates(Item **where);
|
||||||
/*
|
/**
|
||||||
Release memory and, if possible, the open tables held by this execution
|
Release memory and, if possible, the open tables held by this execution
|
||||||
plan (and nested plans). It's used to release some tables before
|
plan (and nested plans). It's used to release some tables before
|
||||||
the end of execution in order to increase concurrency and reduce
|
the end of execution in order to increase concurrency and reduce
|
||||||
memory consumption.
|
memory consumption.
|
||||||
*/
|
*/
|
||||||
void join_free();
|
void join_free();
|
||||||
/* Cleanup this JOIN, possibly for reuse */
|
/** Cleanup this JOIN, possibly for reuse */
|
||||||
void cleanup(bool full);
|
void cleanup(bool full);
|
||||||
void clear();
|
void clear();
|
||||||
bool save_join_tab();
|
bool save_join_tab();
|
||||||
|
|
@ -556,7 +561,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds);
|
||||||
/* from sql_delete.cc, used by opt_range.cc */
|
/* from sql_delete.cc, used by opt_range.cc */
|
||||||
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
|
extern "C" int refpos_order_cmp(void* arg, const void *a,const void *b);
|
||||||
|
|
||||||
/* class to copying an field/item to a key struct */
|
/** class to copying an field/item to a key struct */
|
||||||
|
|
||||||
class store_key :public Sql_alloc
|
class store_key :public Sql_alloc
|
||||||
{
|
{
|
||||||
|
|
@ -582,7 +587,7 @@ public:
|
||||||
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
|
to_field=field_arg->new_key_field(thd->mem_root, field_arg->table,
|
||||||
ptr, null, 1);
|
ptr, null, 1);
|
||||||
}
|
}
|
||||||
virtual ~store_key() {} /* Not actually needed */
|
virtual ~store_key() {} /** Not actually needed */
|
||||||
virtual const char *name() const=0;
|
virtual const char *name() const=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ static const LEX_STRING triggers_file_type=
|
||||||
|
|
||||||
const char * const TRG_EXT= ".TRG";
|
const char * const TRG_EXT= ".TRG";
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Table of .TRG file field descriptors.
|
Table of .TRG file field descriptors.
|
||||||
We have here only one field now because in nearest future .TRG
|
We have here only one field now because in nearest future .TRG
|
||||||
files will be merged into .FRM files (so we don't need something
|
files will be merged into .FRM files (so we don't need something
|
||||||
|
|
@ -216,7 +216,7 @@ File_option sql_modes_parameters=
|
||||||
FILE_OPTIONS_ULLLIST
|
FILE_OPTIONS_ULLLIST
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This must be kept up to date whenever a new option is added to the list
|
This must be kept up to date whenever a new option is added to the list
|
||||||
above, as it specifies the number of required parameters of the trigger in
|
above, as it specifies the number of required parameters of the trigger in
|
||||||
.trg file.
|
.trg file.
|
||||||
|
|
@ -292,23 +292,27 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create or drop trigger for table.
|
Create or drop trigger for table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context (including trigger definition in LEX)
|
||||||
mysql_create_or_drop_trigger()
|
@param tables table list containing one table for which trigger is created.
|
||||||
thd - current thread context (including trigger definition in LEX)
|
@param create whenever we create (TRUE) or drop (FALSE) trigger
|
||||||
tables - table list containing one table for which trigger is created.
|
|
||||||
create - whenever we create (TRUE) or drop (FALSE) trigger
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
This function is mainly responsible for opening and locking of table and
|
This function is mainly responsible for opening and locking of table and
|
||||||
invalidation of all its instances in table cache after trigger creation.
|
invalidation of all its instances in table cache after trigger creation.
|
||||||
Real work on trigger creation/dropping is done inside Table_triggers_list
|
Real work on trigger creation/dropping is done inside Table_triggers_list
|
||||||
methods.
|
methods.
|
||||||
|
|
||||||
RETURN VALUE
|
@todo
|
||||||
|
TODO: We should check if user has TRIGGER privilege for table here.
|
||||||
|
Now we just require SUPER privilege for creating/dropping because
|
||||||
|
we don't have proper privilege checking for triggers in place yet.
|
||||||
|
|
||||||
|
@retval
|
||||||
FALSE Success
|
FALSE Success
|
||||||
|
@retval
|
||||||
TRUE error
|
TRUE error
|
||||||
*/
|
*/
|
||||||
bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||||
|
|
@ -518,29 +522,28 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Create trigger for table.
|
Create trigger for table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context (including trigger definition in
|
||||||
create_trigger()
|
LEX)
|
||||||
thd - current thread context (including trigger definition in
|
@param tables table list containing one open table for which the
|
||||||
LEX)
|
trigger is created.
|
||||||
tables - table list containing one open table for which the
|
@param[out] stmt_query after successful return, this string contains
|
||||||
trigger is created.
|
well-formed statement for creation this trigger.
|
||||||
stmt_query - [OUT] after successful return, this string contains
|
|
||||||
well-formed statement for creating this trigger.
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
- Assumes that trigger name is fully qualified.
|
- Assumes that trigger name is fully qualified.
|
||||||
- NULL-string means the following LEX_STRING instance:
|
- NULL-string means the following LEX_STRING instance:
|
||||||
{ str = 0; length = 0 }.
|
{ str = 0; length = 0 }.
|
||||||
- In other words, definer_user and definer_host should contain
|
- In other words, definer_user and definer_host should contain
|
||||||
simultaneously NULL-strings (non-SUID/old trigger) or valid strings
|
simultaneously NULL-strings (non-SUID/old trigger) or valid strings
|
||||||
(SUID/new trigger).
|
(SUID/new trigger).
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
|
||||||
String *stmt_query)
|
String *stmt_query)
|
||||||
|
|
@ -806,19 +809,18 @@ err_with_cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Deletes the .TRG file for a table
|
Deletes the .TRG file for a table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param path char buffer of size FN_REFLEN to be used
|
||||||
rm_trigger_file()
|
for constructing path to .TRG file.
|
||||||
path - char buffer of size FN_REFLEN to be used
|
@param db table's database name
|
||||||
for constructing path to .TRG file.
|
@param table_name table's name
|
||||||
db - table's database name
|
|
||||||
table_name - table's name
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool rm_trigger_file(char *path, const char *db,
|
static bool rm_trigger_file(char *path, const char *db,
|
||||||
|
|
@ -829,19 +831,18 @@ static bool rm_trigger_file(char *path, const char *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Deletes the .TRN file for a trigger
|
Deletes the .TRN file for a trigger.
|
||||||
|
|
||||||
SYNOPSIS
|
@param path char buffer of size FN_REFLEN to be used
|
||||||
rm_trigname_file()
|
for constructing path to .TRN file.
|
||||||
path - char buffer of size FN_REFLEN to be used
|
@param db trigger's database name
|
||||||
for constructing path to .TRN file.
|
@param table_name trigger's name
|
||||||
db - trigger's database name
|
|
||||||
table_name - trigger's name
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool rm_trigname_file(char *path, const char *db,
|
static bool rm_trigname_file(char *path, const char *db,
|
||||||
|
|
@ -852,17 +853,16 @@ static bool rm_trigname_file(char *path, const char *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Helper function that saves .TRG file for Table_triggers_list object.
|
Helper function that saves .TRG file for Table_triggers_list object.
|
||||||
|
|
||||||
SYNOPSIS
|
@param triggers Table_triggers_list object for which file should be saved
|
||||||
save_trigger_file()
|
@param db Name of database for subject table
|
||||||
triggers Table_triggers_list object for which file should be saved
|
@param table_name Name of subject table
|
||||||
db Name of database for subject table
|
|
||||||
table_name Name of subject table
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
FALSE Success
|
FALSE Success
|
||||||
|
@retval
|
||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -881,21 +881,26 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Drop trigger for table.
|
Drop trigger for table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context
|
||||||
drop_trigger()
|
(including trigger definition in LEX)
|
||||||
thd - current thread context
|
@param tables table list containing one open table for which trigger
|
||||||
(including trigger definition in LEX)
|
is dropped.
|
||||||
tables - table list containing one open table for which trigger
|
@param[out] stmt_query after successful return, this string contains
|
||||||
is dropped.
|
well-formed statement for creation this trigger.
|
||||||
stmt_query - [OUT] after successful return, this string contains
|
|
||||||
well-formed statement for deleting this trigger.
|
|
||||||
|
|
||||||
RETURN VALUE
|
@todo
|
||||||
False - success
|
Probably instead of removing .TRG file we should move
|
||||||
True - error
|
to archive directory but this should be done as part of
|
||||||
|
parse_file.cc functionality (because we will need it
|
||||||
|
elsewhere).
|
||||||
|
|
||||||
|
@retval
|
||||||
|
False success
|
||||||
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
|
bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
|
||||||
String *stmt_query)
|
String *stmt_query)
|
||||||
|
|
@ -978,18 +983,17 @@ Table_triggers_list::~Table_triggers_list()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Prepare array of Field objects referencing to TABLE::record[1] instead
|
Prepare array of Field objects referencing to TABLE::record[1] instead
|
||||||
of record[0] (they will represent OLD.* row values in ON UPDATE trigger
|
of record[0] (they will represent OLD.* row values in ON UPDATE trigger
|
||||||
and in ON DELETE trigger which will be called during REPLACE execution).
|
and in ON DELETE trigger which will be called during REPLACE execution).
|
||||||
|
|
||||||
SYNOPSIS
|
@param table pointer to TABLE object for which we are creating fields.
|
||||||
prepare_record1_accessors()
|
|
||||||
table - pointer to TABLE object for which we are creating fields.
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
||||||
{
|
{
|
||||||
|
|
@ -1018,12 +1022,10 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Adjust Table_triggers_list with new TABLE pointer.
|
Adjust Table_triggers_list with new TABLE pointer.
|
||||||
|
|
||||||
SYNOPSIS
|
@param new_table new pointer to TABLE instance
|
||||||
set_table()
|
|
||||||
new_table - new pointer to TABLE instance
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Table_triggers_list::set_table(TABLE *new_table)
|
void Table_triggers_list::set_table(TABLE *new_table)
|
||||||
|
|
@ -1037,20 +1039,26 @@ void Table_triggers_list::set_table(TABLE *new_table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Check whenever .TRG file for table exist and load all triggers it contains.
|
Check whenever .TRG file for table exist and load all triggers it contains.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context
|
||||||
check_n_load()
|
@param db table's database name
|
||||||
thd - current thread context
|
@param table_name table's name
|
||||||
db - table's database name
|
@param table pointer to table object
|
||||||
table_name - table's name
|
@param names_only stop after loading trigger names
|
||||||
table - pointer to table object
|
|
||||||
names_only - stop after loading trigger names
|
|
||||||
|
|
||||||
RETURN VALUE
|
@todo
|
||||||
False - success
|
A lot of things to do here e.g. how about other funcs and being
|
||||||
True - error
|
more paranoical ?
|
||||||
|
|
||||||
|
@todo
|
||||||
|
This could be avoided if there is no triggers for UPDATE and DELETE.
|
||||||
|
|
||||||
|
@retval
|
||||||
|
False success
|
||||||
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
||||||
|
|
@ -1433,24 +1441,23 @@ err_with_lex_cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Obtains and returns trigger metadata
|
Obtains and returns trigger metadata.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context
|
||||||
get_trigger_info()
|
@param event trigger event type
|
||||||
thd - current thread context
|
@param time_type trigger action time
|
||||||
event - trigger event type
|
@param trigger_name returns name of trigger
|
||||||
time_type - trigger action time
|
@param trigger_stmt returns statement of trigger
|
||||||
name - returns name of trigger
|
@param sql_mode returns sql_mode of trigger
|
||||||
stmt - returns statement of trigger
|
@param definer returns definer/creator of trigger. The caller is
|
||||||
sql_mode - returns sql_mode of trigger
|
responsible to allocate enough space for storing
|
||||||
definer_user - returns definer/creator of trigger. The caller is
|
definer information.
|
||||||
responsible to allocate enough space for storing definer
|
|
||||||
information.
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
|
bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
|
||||||
|
|
@ -1616,21 +1623,20 @@ bool add_table_for_trigger(THD *thd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Drop all triggers for table.
|
Drop all triggers for table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd current thread context
|
||||||
drop_all_triggers()
|
@param db schema for table
|
||||||
thd - current thread context
|
@param name name for table
|
||||||
db - schema for table
|
|
||||||
name - name for table
|
|
||||||
|
|
||||||
NOTE
|
@note
|
||||||
The calling thread should hold the LOCK_open mutex;
|
The calling thread should hold the LOCK_open mutex;
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
False - success
|
False success
|
||||||
True - error
|
@retval
|
||||||
|
True error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
|
bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
|
||||||
|
|
@ -1680,19 +1686,18 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Update .TRG file after renaming triggers' subject table
|
Update .TRG file after renaming triggers' subject table
|
||||||
(change name of table in triggers' definitions).
|
(change name of table in triggers' definitions).
|
||||||
|
|
||||||
SYNOPSIS
|
@param thd Thread context
|
||||||
change_table_name_in_triggers()
|
@param db_name Database of subject table
|
||||||
thd Thread context
|
@param old_table_name Old subject table's name
|
||||||
db_name Database of subject table
|
@param new_table_name New subject table's name
|
||||||
old_table_name Old subject table's name
|
|
||||||
new_table_name New subject table's name
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
FALSE Success
|
FALSE Success
|
||||||
|
@retval
|
||||||
TRUE Failure
|
TRUE Failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1762,21 +1767,20 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Iterate though Table_triggers_list::names_list list and update .TRN files
|
Iterate though Table_triggers_list::names_list list and update
|
||||||
after renaming triggers' subject table.
|
.TRN files after renaming triggers' subject table.
|
||||||
|
|
||||||
SYNOPSIS
|
@param db_name Database of subject table
|
||||||
change_table_name_in_trignames()
|
@param new_table_name New subject table's name
|
||||||
db_name Database of subject table
|
@param stopper Pointer to Table_triggers_list::names_list at
|
||||||
new_table_name New subject table's name
|
which we should stop updating.
|
||||||
stopper Pointer to Table_triggers_list::names_list at
|
|
||||||
which we should stop updating.
|
|
||||||
|
|
||||||
RETURN VALUE
|
@retval
|
||||||
0 Success
|
0 Success
|
||||||
|
@retval
|
||||||
non-0 Failure, pointer to Table_triggers_list::names_list element
|
non-0 Failure, pointer to Table_triggers_list::names_list element
|
||||||
for which update failed.
|
for which update failed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LEX_STRING*
|
LEX_STRING*
|
||||||
|
|
@ -1810,7 +1814,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Update .TRG and .TRN files after renaming triggers' subject table.
|
Update .TRG and .TRN files after renaming triggers' subject table.
|
||||||
|
|
||||||
@param[in,out] thd Thread context
|
@param[in,out] thd Thread context
|
||||||
@param[in] db Old database of subject table
|
@param[in] db Old database of subject table
|
||||||
|
|
@ -1972,19 +1976,17 @@ bool Table_triggers_list::process_triggers(THD *thd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Mark fields of subject table which we read/set in its triggers as such.
|
Mark fields of subject table which we read/set in its triggers
|
||||||
|
as such.
|
||||||
|
|
||||||
SYNOPSIS
|
This method marks fields of subject table which are read/set in its
|
||||||
mark_fields_used()
|
triggers as such (by properly updating TABLE::read_set/write_set)
|
||||||
thd Current thread context
|
and thus informs handler that values for these fields should be
|
||||||
event Type of event triggers for which we are going to ins
|
retrieved/stored during execution of statement.
|
||||||
|
|
||||||
DESCRIPTION
|
@param thd Current thread context
|
||||||
This method marks fields of subject table which are read/set in its
|
@param event Type of event triggers for which we are going to inspect
|
||||||
triggers as such (by properly updating TABLE::read_set/write_set)
|
|
||||||
and thus informs handler that values for these fields should be
|
|
||||||
retrieved/stored during execution of statement.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Table_triggers_list::mark_fields_used(trg_event_type event)
|
void Table_triggers_list::mark_fields_used(trg_event_type event)
|
||||||
|
|
@ -2010,23 +2012,23 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Trigger BUG#14090 compatibility hook
|
Trigger BUG#14090 compatibility hook.
|
||||||
|
|
||||||
SYNOPSIS
|
@param[in,out] unknown_key reference on the line with unknown
|
||||||
Handle_old_incorrect_sql_modes_hook::process_unknown_string()
|
parameter and the parsing point
|
||||||
unknown_key [in/out] reference on the line with unknown
|
@param[in] base base address for parameter writing
|
||||||
parameter and the parsing point
|
(structure like TABLE)
|
||||||
base [in] base address for parameter writing (structure
|
@param[in] mem_root MEM_ROOT for parameters allocation
|
||||||
like TABLE)
|
@param[in] end the end of the configuration
|
||||||
mem_root [in] MEM_ROOT for parameters allocation
|
|
||||||
end [in] the end of the configuration
|
|
||||||
|
|
||||||
NOTE: this hook process back compatibility for incorrectly written
|
@note
|
||||||
sql_modes parameter (see BUG#14090).
|
NOTE: this hook process back compatibility for incorrectly written
|
||||||
|
sql_modes parameter (see BUG#14090).
|
||||||
|
|
||||||
RETURN
|
@retval
|
||||||
FALSE OK
|
FALSE OK
|
||||||
|
@retval
|
||||||
TRUE Error
|
TRUE Error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2068,13 +2070,12 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
#define INVALID_TRIGGER_TABLE_LENGTH 15
|
||||||
|
|
||||||
|
/**
|
||||||
Trigger BUG#15921 compatibility hook. For details see
|
Trigger BUG#15921 compatibility hook. For details see
|
||||||
Handle_old_incorrect_sql_modes_hook::process_unknown_string().
|
Handle_old_incorrect_sql_modes_hook::process_unknown_string().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INVALID_TRIGGER_TABLE_LENGTH 15
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Handle_old_incorrect_trigger_table_hook::
|
Handle_old_incorrect_trigger_table_hook::
|
||||||
process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
|
process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
|
||||||
|
|
@ -2113,9 +2114,9 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
|
||||||
/**
|
/**
|
||||||
Contruct path to TRN-file.
|
Contruct path to TRN-file.
|
||||||
|
|
||||||
@param[in] thd Thread context.
|
@param thd[in] Thread context.
|
||||||
@param[in] trg_name Trigger name.
|
@param trg_name[in] Trigger name.
|
||||||
@param[out] trn_path Variable to store constructed path
|
@param trn_path[out] Variable to store constructed path
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
|
void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
|
||||||
|
|
@ -2148,10 +2149,10 @@ bool check_trn_exists(const LEX_STRING *trn_path)
|
||||||
/**
|
/**
|
||||||
Retrieve table name for given trigger.
|
Retrieve table name for given trigger.
|
||||||
|
|
||||||
@param[in] thd Thread context.
|
@param thd[in] Thread context.
|
||||||
@param[in] trg_name Trigger name.
|
@param trg_name[in] Trigger name.
|
||||||
@param[in] trn_path Path to the corresponding TRN-file.
|
@param trn_path[in] Path to the corresponding TRN-file.
|
||||||
@param[out] tbl_name Variable to store retrieved table name.
|
@param tbl_name[out] Variable to store retrieved table name.
|
||||||
|
|
||||||
@return Error status.
|
@return Error status.
|
||||||
@retval FALSE on success.
|
@retval FALSE on success.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This class holds all information about triggers of table.
|
This class holds all information about triggers of table.
|
||||||
|
|
||||||
QQ: Will it be merged into TABLE in the future ?
|
QQ: Will it be merged into TABLE in the future ?
|
||||||
|
|
@ -22,20 +22,20 @@
|
||||||
|
|
||||||
class Table_triggers_list: public Sql_alloc
|
class Table_triggers_list: public Sql_alloc
|
||||||
{
|
{
|
||||||
/* Triggers as SPs grouped by event, action_time */
|
/** Triggers as SPs grouped by event, action_time */
|
||||||
sp_head *bodies[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
sp_head *bodies[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||||
/*
|
/**
|
||||||
Heads of the lists linking items for all fields used in triggers
|
Heads of the lists linking items for all fields used in triggers
|
||||||
grouped by event and action_time.
|
grouped by event and action_time.
|
||||||
*/
|
*/
|
||||||
Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||||
/*
|
/**
|
||||||
Copy of TABLE::Field array with field pointers set to TABLE::record[1]
|
Copy of TABLE::Field array with field pointers set to TABLE::record[1]
|
||||||
buffer instead of TABLE::record[0] (used for OLD values in on UPDATE
|
buffer instead of TABLE::record[0] (used for OLD values in on UPDATE
|
||||||
trigger and DELETE trigger when it is called for REPLACE).
|
trigger and DELETE trigger when it is called for REPLACE).
|
||||||
*/
|
*/
|
||||||
Field **record1_field;
|
Field **record1_field;
|
||||||
/*
|
/**
|
||||||
During execution of trigger new_field and old_field should point to the
|
During execution of trigger new_field and old_field should point to the
|
||||||
array of fields representing new or old version of row correspondingly
|
array of fields representing new or old version of row correspondingly
|
||||||
(so it can point to TABLE::field or to Tale_triggers_list::record1_field)
|
(so it can point to TABLE::field or to Tale_triggers_list::record1_field)
|
||||||
|
|
@ -45,30 +45,30 @@ class Table_triggers_list: public Sql_alloc
|
||||||
|
|
||||||
/* TABLE instance for which this triggers list object was created */
|
/* TABLE instance for which this triggers list object was created */
|
||||||
TABLE *trigger_table;
|
TABLE *trigger_table;
|
||||||
/*
|
/**
|
||||||
Names of triggers.
|
Names of triggers.
|
||||||
Should correspond to order of triggers on definitions_list,
|
Should correspond to order of triggers on definitions_list,
|
||||||
used in CREATE/DROP TRIGGER for looking up trigger by name.
|
used in CREATE/DROP TRIGGER for looking up trigger by name.
|
||||||
*/
|
*/
|
||||||
List<LEX_STRING> names_list;
|
List<LEX_STRING> names_list;
|
||||||
/*
|
/**
|
||||||
List of "ON table_name" parts in trigger definitions, used for
|
List of "ON table_name" parts in trigger definitions, used for
|
||||||
updating trigger definitions during RENAME TABLE.
|
updating trigger definitions during RENAME TABLE.
|
||||||
*/
|
*/
|
||||||
List<LEX_STRING> on_table_names_list;
|
List<LEX_STRING> on_table_names_list;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Grant information for each trigger (pair: subject table, trigger definer).
|
Grant information for each trigger (pair: subject table, trigger definer).
|
||||||
*/
|
*/
|
||||||
GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*
|
/**
|
||||||
Field responsible for storing triggers definitions in file.
|
Field responsible for storing triggers definitions in file.
|
||||||
It have to be public because we are using it directly from parser.
|
It have to be public because we are using it directly from parser.
|
||||||
*/
|
*/
|
||||||
List<LEX_STRING> definitions_list;
|
List<LEX_STRING> definitions_list;
|
||||||
/*
|
/**
|
||||||
List of sql modes for triggers
|
List of sql modes for triggers
|
||||||
*/
|
*/
|
||||||
List<ulonglong> definition_modes_list;
|
List<ulonglong> definition_modes_list;
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ static bool check_fields(THD *thd, List<Item> &items)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Re-read record if more columns are needed for error message.
|
Re-read record if more columns are needed for error message.
|
||||||
|
|
||||||
If we got a duplicate key error, we want to write an error
|
If we got a duplicate key error, we want to write an error
|
||||||
message containing the value of the duplicate key. If we do not have
|
message containing the value of the duplicate key. If we do not have
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Creating/altering VIEW procedure
|
Creating/altering VIEW procedure
|
||||||
|
|
||||||
@param thd thread handler
|
@param thd thread handler
|
||||||
@param views views to create
|
@param views views to create
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,7 @@ typedef struct user_conn {
|
||||||
char *user;
|
char *user;
|
||||||
/* Pointer to host part of the key. */
|
/* Pointer to host part of the key. */
|
||||||
char *host;
|
char *host;
|
||||||
/*
|
/**
|
||||||
The moment of time when per hour counters were reset last time
|
The moment of time when per hour counters were reset last time
|
||||||
(i.e. start of "hour" for conn_per_hour, updates, questions counters).
|
(i.e. start of "hour" for conn_per_hour, updates, questions counters).
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
12
sql/tztime.h
12
sql/tztime.h
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#if !defined(TESTTIME) && !defined(TZINFO2SQL)
|
#if !defined(TESTTIME) && !defined(TZINFO2SQL)
|
||||||
|
|
||||||
/*
|
/**
|
||||||
This class represents abstract time zone and provides
|
This class represents abstract time zone and provides
|
||||||
basic interface for MYSQL_TIME <-> my_time_t conversion.
|
basic interface for MYSQL_TIME <-> my_time_t conversion.
|
||||||
Actual time zones which are specified by DB, or via offset
|
Actual time zones which are specified by DB, or via offset
|
||||||
|
|
@ -30,7 +30,7 @@ class Time_zone: public Sql_alloc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Time_zone() {} /* Remove gcc warning */
|
Time_zone() {} /* Remove gcc warning */
|
||||||
/*
|
/**
|
||||||
Converts local time in broken down MYSQL_TIME representation to
|
Converts local time in broken down MYSQL_TIME representation to
|
||||||
my_time_t (UTC seconds since Epoch) represenation.
|
my_time_t (UTC seconds since Epoch) represenation.
|
||||||
Returns 0 in case of error. Sets in_dst_time_gap to true if date provided
|
Returns 0 in case of error. Sets in_dst_time_gap to true if date provided
|
||||||
|
|
@ -38,19 +38,19 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
||||||
my_bool *in_dst_time_gap) const = 0;
|
my_bool *in_dst_time_gap) const = 0;
|
||||||
/*
|
/**
|
||||||
Converts time in my_time_t representation to local time in
|
Converts time in my_time_t representation to local time in
|
||||||
broken down MYSQL_TIME representation.
|
broken down MYSQL_TIME representation.
|
||||||
*/
|
*/
|
||||||
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0;
|
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const = 0;
|
||||||
/*
|
/**
|
||||||
Because of constness of String returned by get_name() time zone name
|
Because of constness of String returned by get_name() time zone name
|
||||||
have to be already zeroended to be able to use String::ptr() instead
|
have to be already zeroended to be able to use String::ptr() instead
|
||||||
of c_ptr().
|
of c_ptr().
|
||||||
*/
|
*/
|
||||||
virtual const String * get_name() const = 0;
|
virtual const String * get_name() const = 0;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
We need this only for surpressing warnings, objects of this type are
|
We need this only for surpressing warnings, objects of this type are
|
||||||
allocated on MEM_ROOT and should not require destruction.
|
allocated on MEM_ROOT and should not require destruction.
|
||||||
*/
|
*/
|
||||||
|
|
@ -65,7 +65,7 @@ extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool
|
||||||
extern void my_tz_free();
|
extern void my_tz_free();
|
||||||
extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
|
extern my_time_t sec_since_epoch_TIME(MYSQL_TIME *t);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
Number of elements in table list produced by my_tz_get_table_list()
|
Number of elements in table list produced by my_tz_get_table_list()
|
||||||
(this table list contains tables which are needed for dynamical loading
|
(this table list contains tables which are needed for dynamical loading
|
||||||
of time zone descriptions). Actually it is imlementation detail that
|
of time zone descriptions). Actually it is imlementation detail that
|
||||||
|
|
|
||||||
10
sql/unireg.h
10
sql/unireg.h
|
|
@ -155,34 +155,34 @@
|
||||||
#define OPEN_VIEW 8192 /* Allow open on view */
|
#define OPEN_VIEW 8192 /* Allow open on view */
|
||||||
#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view,
|
#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view,
|
||||||
but do not parse view itself */
|
but do not parse view itself */
|
||||||
/*
|
/**
|
||||||
This flag is used in function get_all_tables() which fills
|
This flag is used in function get_all_tables() which fills
|
||||||
I_S tables with data which are retrieved from frm files and storage engine
|
I_S tables with data which are retrieved from frm files and storage engine
|
||||||
The flag means that we need to open FRM file only to get necessary data.
|
The flag means that we need to open FRM file only to get necessary data.
|
||||||
*/
|
*/
|
||||||
#define OPEN_FRM_FILE_ONLY 32768
|
#define OPEN_FRM_FILE_ONLY 32768
|
||||||
/*
|
/**
|
||||||
This flag is used in function get_all_tables() which fills
|
This flag is used in function get_all_tables() which fills
|
||||||
I_S tables with data which are retrieved from frm files and storage engine
|
I_S tables with data which are retrieved from frm files and storage engine
|
||||||
The flag means that we need to process tables only to get necessary data.
|
The flag means that we need to process tables only to get necessary data.
|
||||||
Views are not processed.
|
Views are not processed.
|
||||||
*/
|
*/
|
||||||
#define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2
|
#define OPEN_TABLE_ONLY OPEN_FRM_FILE_ONLY*2
|
||||||
/*
|
/**
|
||||||
This flag is used in function get_all_tables() which fills
|
This flag is used in function get_all_tables() which fills
|
||||||
I_S tables with data which are retrieved from frm files and storage engine
|
I_S tables with data which are retrieved from frm files and storage engine
|
||||||
The flag means that we need to process views only to get necessary data.
|
The flag means that we need to process views only to get necessary data.
|
||||||
Tables are not processed.
|
Tables are not processed.
|
||||||
*/
|
*/
|
||||||
#define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2
|
#define OPEN_VIEW_ONLY OPEN_TABLE_ONLY*2
|
||||||
/*
|
/**
|
||||||
This flag is used in function get_all_tables() which fills
|
This flag is used in function get_all_tables() which fills
|
||||||
I_S tables with data which are retrieved from frm files and storage engine.
|
I_S tables with data which are retrieved from frm files and storage engine.
|
||||||
The flag means that we need to open a view using
|
The flag means that we need to open a view using
|
||||||
open_normal_and_derived_tables() function.
|
open_normal_and_derived_tables() function.
|
||||||
*/
|
*/
|
||||||
#define OPEN_VIEW_FULL OPEN_VIEW_ONLY*2
|
#define OPEN_VIEW_FULL OPEN_VIEW_ONLY*2
|
||||||
/*
|
/**
|
||||||
This flag is used in function get_all_tables() which fills
|
This flag is used in function get_all_tables() which fills
|
||||||
I_S tables with data which are retrieved from frm files and storage engine.
|
I_S tables with data which are retrieved from frm files and storage engine.
|
||||||
The flag means that I_S table uses optimization algorithm.
|
The flag means that I_S table uses optimization algorithm.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue