Merge bk-internal:/home/bk/mysql-5.0

into serg.mylan:/usr/home/serg/Abk/mysql-5.0
This commit is contained in:
serg@serg.mylan 2005-03-22 16:11:43 +01:00
commit e029e3eb61
80 changed files with 881 additions and 483 deletions

View file

@ -48,6 +48,7 @@ dlenev@build.mysql.com
dlenev@jabberwock.localdomain
dlenev@mysql.com
ejonore@mc03.ndb.mysql.com
gbichot@production.mysql.com
gbichot@quadita2.mysql.com
gbichot@quadxeon.mysql.com
georg@beethoven.local

View file

@ -595,3 +595,5 @@ character-set=latin1
"Invalid ON UPDATE clause for '%-.64s' field",
#define ER_UNSUPPORTED_PS 1295
"This command is not supported in the prepared statement protocol yet",
#define ER_CANT_CREATE_USER_WITH_GRANT 1296
"You are not allowed to create a user with GRANT"

View file

@ -33,9 +33,9 @@
#undef MYSQL_SERVER
#include "client_priv.h"
#include <my_time.h>
#include "log_event.h"
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
#include "mysql_priv.h"
#include "log_event.h"
#define BIN_LOG_HEADER_SIZE 4
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)

View file

@ -1093,7 +1093,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
number of fields in table, 0 if error
*/
static uint getTableStructure(char *table, char* db)
static uint getTableStructure(char *table, char *db)
{
MYSQL_RES *tableRes;
MYSQL_ROW row;
@ -1396,10 +1396,9 @@ static uint getTableStructure(char *table, char* db)
/* Get MySQL specific create options */
if (create_options)
{
char show_name_buff[FN_REFLEN];
char show_name_buff[NAME_LEN*2+2+24];
/* Check memory for quote_for_like() */
DBUG_ASSERT(2*sizeof(table) < sizeof(show_name_buff));
my_snprintf(buff, sizeof(buff), "show table status like %s",
quote_for_like(table, show_name_buff));

View file

@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# Don't forget to also update the NDB lines below.
AM_INIT_AUTOMAKE(mysql, 5.0.3-alpha)
AM_INIT_AUTOMAKE(mysql, 5.0.3-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@ -18,7 +18,7 @@ SHARED_LIB_VERSION=14:0:0
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=3
NDB_VERSION_STATUS="alpha"
NDB_VERSION_STATUS="beta"
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4

View file

@ -80,6 +80,9 @@ extern "C" {
/* On NetWare, stack grows towards lower address*/
#define STACK_DIRECTION -1
/* On NetWare, to fix the problem with the deletion of open files */
#define CANT_DELETE_OPEN_FILES 1
/* default directory information */
#define DEFAULT_MYSQL_HOME "sys:/mysql"
#define PACKAGE "mysql"

View file

@ -20,47 +20,50 @@
typedef enum
{TRUNCATE=0, HALF_EVEN, HALF_UP, CEILING, FLOOR}
decimal_round_mode;
typedef int32 decimal_digit;
typedef int32 decimal_digit_t;
typedef struct st_decimal {
typedef struct st_decimal_t {
int intg, frac, len;
my_bool sign;
decimal_digit *buf;
} decimal;
decimal_digit_t *buf;
} decimal_t;
int internal_str2dec(const char *from, decimal *to, char **end, my_bool fixed);
int decimal2string(decimal *from, char *to, int *to_len,
int internal_str2dec(const char *from, decimal_t *to, char **end,
my_bool fixed);
int decimal2string(decimal_t *from, char *to, int *to_len,
int fixed_precision, int fixed_decimals,
char filler);
int decimal2ulonglong(decimal *from, ulonglong *to);
int ulonglong2decimal(ulonglong from, decimal *to);
int decimal2longlong(decimal *from, longlong *to);
int longlong2decimal(longlong from, decimal *to);
int decimal2double(decimal *from, double *to);
int double2decimal(double from, decimal *to);
void decimal_optimize_fraction(decimal *from);
int decimal2bin(decimal *from, char *to, int precision, int scale);
int bin2decimal(char *from, decimal *to, int precision, int scale);
int decimal2ulonglong(decimal_t *from, ulonglong *to);
int ulonglong2decimal(ulonglong from, decimal_t *to);
int decimal2longlong(decimal_t *from, longlong *to);
int longlong2decimal(longlong from, decimal_t *to);
int decimal2double(decimal_t *from, double *to);
int double2decimal(double from, decimal_t *to);
void decimal_optimize_fraction(decimal_t *from);
int decimal2bin(decimal_t *from, char *to, int precision, int scale);
int bin2decimal(char *from, decimal_t *to, int precision, int scale);
int decimal_size(int precision, int scale);
int decimal_bin_size(int precision, int scale);
int decimal_result_size(decimal *from1, decimal *from2, char op, int param);
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,
int param);
int decimal_add(decimal *from1, decimal *from2, decimal *to);
int decimal_sub(decimal *from1, decimal *from2, decimal *to);
int decimal_cmp(decimal *from1, decimal *from2);
int decimal_mul(decimal *from1, decimal *from2, decimal *to);
int decimal_div(decimal *from1, decimal *from2, decimal *to, int scale_incr);
int decimal_mod(decimal *from1, decimal *from2, decimal *to);
int decimal_round(decimal *from, decimal *to, int new_scale,
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to);
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to);
int decimal_cmp(decimal_t *from1, decimal_t *from2);
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to);
int decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to,
int scale_incr);
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to);
int decimal_round(decimal_t *from, decimal_t *to, int new_scale,
decimal_round_mode mode);
int decimal_is_zero(decimal *from);
void max_decimal(int precision, int frac, decimal *to);
int decimal_is_zero(decimal_t *from);
void max_decimal(int precision, int frac, decimal_t *to);
#define string2decimal(A,B,C) internal_str2dec((A), (B), (C), 0)
#define string2decimal_fixed(A,B,C) internal_str2dec((A), (B), (C), 1)
/* set a decimal to zero */
/* set a decimal_t to zero */
#define decimal_make_zero(dec) do { \
(dec)->buf[0]=0; \

View file

@ -381,6 +381,12 @@ struct trx_struct{
in MySQL's binlog write, we will
flush the log to disk later in
a separate call */
ibool must_flush_log_later;/* this flag is set to TRUE in
trx_commit_off_kernel() if
flush_log_later was TRUE, and there
were modifications by the transaction;
in that case we must flush the log
in trx_commit_complete_for_mysql() */
dulint commit_lsn; /* lsn at the time of the commit */
ibool dict_operation; /* TRUE if the trx is used to create
a table, create an index, or drop a

View file

@ -99,6 +99,7 @@ trx_create(
trx->check_unique_secondary = TRUE;
trx->flush_log_later = FALSE;
trx->must_flush_log_later = FALSE;
trx->dict_operation = FALSE;
@ -710,6 +711,8 @@ trx_commit_off_kernel(
ut_ad(mutex_own(&kernel_mutex));
#endif /* UNIV_SYNC_DEBUG */
trx->must_flush_log_later = FALSE;
rseg = trx->rseg;
if (trx->insert_undo != NULL || trx->update_undo != NULL) {
@ -875,6 +878,7 @@ trx_commit_off_kernel(
if (trx->flush_log_later) {
/* Do nothing yet */
trx->must_flush_log_later = TRUE;
} else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
} else if (srv_flush_log_at_trx_commit == 1) {
@ -1594,7 +1598,9 @@ trx_commit_complete_for_mysql(
trx->op_info = "flushing log";
if (srv_flush_log_at_trx_commit == 0) {
if (!trx->must_flush_log_later) {
/* Do nothing */
} else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
} else if (srv_flush_log_at_trx_commit == 1) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
@ -1615,6 +1621,8 @@ trx_commit_complete_for_mysql(
} else {
ut_error;
}
trx->must_flush_log_later = FALSE;
trx->op_info = "";

View file

@ -16,6 +16,11 @@ CREATE TABLE db (
Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
PRIMARY KEY Host (Host,Db,User),
KEY User (User)
) engine=MyISAM
@ -23,8 +28,8 @@ CHARACTER SET utf8 COLLATE utf8_bin
comment='Database privileges';
INSERT INTO db VALUES ('%','test' ,'','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y','Y','Y','Y','N','N');
CREATE TABLE host (
@ -42,6 +47,8 @@ CREATE TABLE host (
Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
PRIMARY KEY Host (Host,Db)
) engine=MyISAM
CHARACTER SET utf8 COLLATE utf8_bin
@ -73,6 +80,10 @@ CREATE TABLE user (
Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL,
ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL,
ssl_cipher BLOB NOT NULL,
x509_issuer BLOB NOT NULL,
@ -80,15 +91,16 @@ CREATE TABLE user (
max_questions int(11) unsigned DEFAULT 0 NOT NULL,
max_updates int(11) unsigned DEFAULT 0 NOT NULL,
max_connections int(11) unsigned DEFAULT 0 NOT NULL,
max_user_connections int(11) unsigned DEFAULT 0 NOT NULL,
PRIMARY KEY Host (Host,User)
) engine=MyISAM
CHARACTER SET utf8 COLLATE utf8_bin
comment='Users and global privileges';
INSERT INTO user VALUES ('localhost' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('@HOSTNAME@%','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
REPLACE INTO user VALUES ('127.0.0.1' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('localhost' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user VALUES ('@HOSTNAME@%' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
REPLACE INTO user VALUES ('127.0.0.1' ,'root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0,0);
INSERT INTO user (host,user) VALUES ('localhost','');
INSERT INTO user (host,user) VALUES ('@HOSTNAME@%','');
@ -468,3 +480,74 @@ INSERT INTO time_zone_leap_second (
,(662688015, 16) ,(709948816, 17) ,(741484817, 18)
,(773020818, 19) ,(820454419, 20) ,(867715220, 21)
,(915148821, 22);
CREATE TABLE procs_priv (
Host char(60) binary DEFAULT '' NOT NULL,
Db char(64) binary DEFAULT '' NOT NULL,
User char(16) binary DEFAULT '' NOT NULL,
Routine_name char(64) binary DEFAULT '' NOT NULL,
Grantor char(77) DEFAULT '' NOT NULL,
Timestamp timestamp(14),
Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL,
PRIMARY KEY (Host,Db,User,Routine_name),
KEY Grantor (Grantor)
) engine=MyISAM
CHARACTER SET utf8 COLLATE utf8_bin
comment='Procedure privileges';
CREATE TABLE proc (
db char(64) binary DEFAULT '' NOT NULL,
name char(64) DEFAULT '' NOT NULL,
type enum('FUNCTION','PROCEDURE') NOT NULL,
specific_name char(64) DEFAULT '' NOT NULL,
language enum('SQL') DEFAULT 'SQL' NOT NULL,
sql_data_access enum('CONTAINS_SQL',
'NO_SQL',
'READS_SQL_DATA',
'MODIFIES_SQL_DATA'
) DEFAULT 'CONTAINS_SQL' NOT NULL,
is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL,
security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL,
param_list blob DEFAULT '' NOT NULL,
returns char(64) DEFAULT '' NOT NULL,
body blob DEFAULT '' NOT NULL,
definer char(77) binary DEFAULT '' NOT NULL,
created timestamp,
modified timestamp,
sql_mode set(
'REAL_AS_FLOAT',
'PIPES_AS_CONCAT',
'ANSI_QUOTES',
'IGNORE_SPACE',
'NOT_USED',
'ONLY_FULL_GROUP_BY',
'NO_UNSIGNED_SUBTRACTION',
'NO_DIR_IN_CREATE',
'POSTGRESQL',
'ORACLE',
'MSSQL',
'DB2',
'MAXDB',
'NO_KEY_OPTIONS',
'NO_TABLE_OPTIONS',
'NO_FIELD_OPTIONS',
'MYSQL323',
'MYSQL40',
'ANSI',
'NO_AUTO_VALUE_ON_ZERO',
'NO_BACKSLASH_ESCAPES',
'STRICT_TRANS_TABLES',
'STRICT_ALL_TABLES',
'NO_ZERO_IN_DATE',
'NO_ZERO_DATE',
'INVALID_DATES',
'ERROR_FOR_DIVISION_BY_ZERO',
'TRADITIONAL',
'NO_AUTO_CREATE_USER',
'HIGH_NOT_PRECEDENCE'
) DEFAULT 0 NOT NULL,
comment char(64) binary DEFAULT '' NOT NULL,
PRIMARY KEY (db,name,type)
) comment='Stored Procedures';

View file

@ -63,21 +63,24 @@ sub collect_test_cases ($) {
# To speed things up, we sort first in if the test require a restart
# or not, second in alphanumeric order.
# @$cases = sort {
# if ( $a->{'master_restart'} and $b->{'master_restart'} or
# ! $a->{'master_restart'} and ! $b->{'master_restart'} )
# {
# return $a->{'name'} cmp $b->{'name'};
# }
# if ( $a->{'master_restart'} )
# {
# return 1; # Is greater
# }
# else
# {
# return -1; # Is less
# }
# } @$cases;
if ( $::opt_reorder )
{
@$cases = sort {
if ( $a->{'master_restart'} and $b->{'master_restart'} or
! $a->{'master_restart'} and ! $b->{'master_restart'} )
{
return $a->{'name'} cmp $b->{'name'};
}
if ( $a->{'master_restart'} )
{
return 1; # Is greater
}
else
{
return -1; # Is less
}
} @$cases;
}
return $cases;
}

View file

@ -89,12 +89,11 @@ sub mtr_report_test_passed ($) {
my $tinfo= shift;
my $timer= "";
# FIXME
# if ( $::opt_timer and -f "$::glob_mysql_test_dir/var/log/timer" )
# {
# $timer= `cat var/log/timer`;
# $timer= sprintf "%13s", $timer;
# }
if ( $::opt_timer and -f "$::glob_mysql_test_dir/var/log/timer" )
{
$timer= mtr_fromfile("$::glob_mysql_test_dir/var/log/timer");
$timer= sprintf "%12s", $timer;
}
$tinfo->{'result'}= 'MTR_RES_PASSED';
print "[ pass ] $timer\n";
}

View file

@ -214,6 +214,7 @@ our $opt_embedded_server;
our $opt_extern;
our $opt_fast;
our $opt_force;
our $opt_reorder;
our $opt_gcov;
our $opt_gcov_err;
@ -525,6 +526,7 @@ sub command_line_setup () {
'local-master' => \$opt_local_master,
'netware' => \$opt_netware,
'old-master' => \$opt_old_master,
'reorder' => \$opt_reorder,
'script-debug' => \$opt_script_debug,
'sleep=i' => \$opt_sleep,
'socket=s' => \$opt_socket,
@ -576,7 +578,7 @@ sub command_line_setup () {
$slave->[0]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave.pid";
$slave->[0]->{'path_mysock'}= "$opt_tmpdir/slave.sock";
$slave->[0]->{'path_myport'}= $opt_slave_myport;
$slave->[0]->{'start_timeout'}= 400;
$slave->[0]->{'start_timeout'}= 400;
$slave->[1]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave1-data";
$slave->[1]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave1.err";
@ -584,7 +586,7 @@ sub command_line_setup () {
$slave->[1]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave1.pid";
$slave->[1]->{'path_mysock'}= "$opt_tmpdir/slave1.sock";
$slave->[1]->{'path_myport'}= $opt_slave_myport + 1;
$slave->[1]->{'start_timeout'}= 30;
$slave->[1]->{'start_timeout'}= 300;
$slave->[2]->{'path_myddir'}= "$glob_mysql_test_dir/var/slave2-data";
$slave->[2]->{'path_myerr'}= "$glob_mysql_test_dir/var/log/slave2.err";
@ -592,7 +594,7 @@ sub command_line_setup () {
$slave->[2]->{'path_mypid'}= "$glob_mysql_test_dir/var/run/slave2.pid";
$slave->[2]->{'path_mysock'}= "$opt_tmpdir/slave2.sock";
$slave->[2]->{'path_myport'}= $opt_slave_myport + 2;
$slave->[2]->{'start_timeout'}= 30;
$slave->[2]->{'start_timeout'}= 300;
# Do sanity checks of command line arguments
@ -1365,7 +1367,10 @@ sub run_testcase ($) {
mtr_report_test_name($tinfo);
mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n");
do_before_start_master($tname,$tinfo->{'master_sh'});
# FIXME test cases that depend on each other, prevent this from
# being at this location.
# do_before_start_master($tname,$tinfo->{'master_sh'});
# ----------------------------------------------------------------------
# If any mysqld servers running died, we have to know
@ -1397,6 +1402,8 @@ sub run_testcase ($) {
}
if ( ! $master->[0]->{'pid'} )
{
# FIXME not correct location for do_before_start_master()
do_before_start_master($tname,$tinfo->{'master_sh'});
$master->[0]->{'pid'}=
mysqld_start('master',0,$tinfo->{'master_opt'},[]);
if ( ! $master->[0]->{'pid'} )
@ -1532,9 +1539,10 @@ sub do_before_start_master ($$) {
$tname ne "rpl_crash_binlog_ib_3b")
{
# FIXME we really want separate dir for binlogs
# FIXME replace 'rm' in backticks with portable Perl function
`rm -f $glob_mysql_test_dir/var/log/master-bin*`;
# unlink("$glob_mysql_test_dir/var/log/master-bin*");
foreach my $bin ( glob("$glob_mysql_test_dir/var/log/master*-bin.*") )
{
unlink($bin);
}
}
# Remove old master.info and relay-log.info files
@ -1568,9 +1576,10 @@ sub do_before_start_slave ($$) {
$tname ne "rpl_crash_binlog_ib_3b" )
{
# FIXME we really want separate dir for binlogs
# FIXME replace 'rm' in backticks with portable Perl function
`rm -fr $glob_mysql_test_dir/var/log/slave*-bin.*`;
# unlink("$glob_mysql_test_dir/var/log/slave*-bin.*"); # FIXME idx???
foreach my $bin ( glob("$glob_mysql_test_dir/var/log/slave*-bin.*") )
{
unlink($bin);
}
# FIXME really master?!
unlink("$glob_mysql_test_dir/var/slave-data/master.info");
unlink("$glob_mysql_test_dir/var/slave-data/relay-log.info");
@ -1656,13 +1665,15 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--datadir=%s", $prefix,
$slave->[$idx]->{'path_myddir'});
% FIXME slave get this option twice?!
mtr_add_arg($args, "%s--exit-info=256", $prefix);
mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix);
mtr_add_arg($args, "%s--log-bin=%s/var/log/slave%s-bin", $prefix,
$glob_mysql_test_dir, $sidx); # FIXME use own dir for binlogs
mtr_add_arg($args, "%s--log-slave-updates", $prefix);
% FIXME option duplicated for slave
mtr_add_arg($args, "%s--log=%s", $prefix,
$slave->[$idx]->{'path_myerr'});
$slave->[$idx]->{'path_mylog'});
mtr_add_arg($args, "%s--master-retry-count=10", $prefix);
mtr_add_arg($args, "%s--pid-file=%s", $prefix,
$slave->[$idx]->{'path_mypid'});
@ -2043,7 +2054,7 @@ sub run_mysqltest ($$) {
if ( $opt_timer )
{
mtr_add_arg($args, "--timer-file=var/log/timer");
mtr_add_arg($args, "--timer-file=%s/var/log/timer", $glob_mysql_test_dir);
}
if ( $opt_big_test )
@ -2172,6 +2183,7 @@ Misc options
timer Show test case execution time
start-and-exit Only initiate and start the "mysqld" servers
fast Don't try to cleanup from earlier runs
reorder Reorder tests to get less server restarts
help Get this help text
unified-diff | udiff When presenting differences, use unified diff

View file

@ -238,7 +238,7 @@ SLEEP_TIME_FOR_DELETE=10
SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables
SLEEP_TIME_FOR_SECOND_MASTER=400
SLEEP_TIME_FOR_FIRST_SLAVE=400
SLEEP_TIME_FOR_SECOND_SLAVE=30
SLEEP_TIME_FOR_SECOND_SLAVE=300
CHARACTER_SET=latin1
DBUSER=""
START_WAIT_TIMEOUT=10

View file

@ -165,7 +165,7 @@ GRANT UPDATE (c2) ON "test"."t2" TO 'mysqltest_1'@'%'
GRANT UPDATE ON "test"."t1" TO 'mysqltest_1'@'%'
drop user 'mysqltest_1', 'mysqltest_3';
grant all on test.t1 to 'mysqltest_1';
ERROR 42000: 'root'@'localhost' is not allowed to create new users
ERROR HY000: You are not allowed to create a user with GRANT
drop user 'mysqltest_1';
ERROR HY000: Operation DROP USER failed for 'mysqltest_1'@'%'
drop table t1, t2;

View file

@ -0,0 +1,17 @@
SET NAMES binary;
drop table if exists t1;
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';
delete from mysql.columns_priv where user like 'mysqltest\_%';
flush privileges;
create user mysqltest_1@localhost;
grant grant option on mysql.* to mysqltest_1@localhost;
grant select on `my\_1`.* to mysqltest_1@localhost with grant option;
grant select on `my\_1`.* to mysqltest_2@localhost;
ERROR HY000: You are not allowed to create a user with GRANT
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';
delete from mysql.columns_priv where user like 'mysqltest\_%';
flush privileges;

View file

@ -118,8 +118,8 @@ t2
t3
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t2 MyISAM 9 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
t3 MyISAM 9 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
t2 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
t3 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL view
show full columns from t3 like "a%";
Field Type Collation Null Key Default Extra Privileges Comment
@ -432,7 +432,6 @@ information_schema.tables) union select version from
information_schema.tables;
s1
0
9
10
drop table t1;
SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets;

View file

@ -144,8 +144,8 @@ Handler_discover 1
flush tables;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t6 MyISAM 9 Fixed 1 260 # # # 0 NULL # # NULL # NULL #
t7 ndbcluster 9 Fixed 1 276 # # # 0 NULL # # NULL # NULL #
t6 MyISAM 10 Fixed 1 260 # # # 0 NULL # # NULL # NULL #
t7 ndbcluster 10 Fixed 1 276 # # # 0 NULL # # NULL # NULL #
show status like 'handler_discover%';
Variable_name Value
Handler_discover 2

View file

@ -378,6 +378,51 @@ a sum(b)
2 6
4 4
NULL 14
SELECT b, a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
b a sum(b)
4 1 4
NULL 1 4
1 2 2
2 2 4
NULL 2 6
1 4 4
NULL 4 4
NULL NULL 14
SELECT DISTINCT b,a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
b a sum(b)
4 1 4
NULL 1 4
1 2 2
2 2 4
NULL 2 6
1 4 4
NULL 4 4
NULL NULL 14
ALTER TABLE t1 ADD COLUMN c INT;
SELECT a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP;
a b sum(c)
1 4 NULL
1 4 NULL
1 NULL NULL
2 1 NULL
2 1 NULL
2 2 NULL
2 2 NULL
2 NULL NULL
4 1 NULL
4 1 NULL
4 NULL NULL
NULL NULL NULL
SELECT distinct a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP;
a b sum(c)
1 4 NULL
1 NULL NULL
2 1 NULL
2 2 NULL
2 NULL NULL
4 1 NULL
4 NULL NULL
NULL NULL NULL
DROP TABLE t1;
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES

View file

@ -290,7 +290,7 @@ t2 1 t2_idx 1 b A NULL NULL NULL YES BTREE
prepare stmt4 from ' show table status from test like ''t2%'' ';
execute stmt4;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t2 MyISAM 9 Fixed 0 0 0 64424509439 1024 0 NULL # # # latin1_swedish_ci NULL
t2 MyISAM 10 Fixed 0 0 0 64424509439 1024 0 NULL # # # latin1_swedish_ci NULL
prepare stmt4 from ' show table status from test like ''t9%'' ';
execute stmt4;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment

View file

@ -4,21 +4,31 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set timestamp=100000000;
create table t1 (t timestamp);
create table t2 (t char(32));
select @@time_zone;
@@time_zone
Japan
select @@time_zone;
@@time_zone
Europe/Moscow
insert into t1 values ('20050101000000'), ('20050611093902');
set time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
t
2004-12-31 21:00:00
2005-06-11 05:39:02
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='UTC';
select * from t1;
t
2004-01-01 03:00:00
2004-06-11 13:39:02
2004-12-31 21:00:00
2005-06-11 05:39:02
2004-01-01 00:00:00
2004-06-11 09:39:02
delete from t1;
set time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
@ -26,19 +36,35 @@ select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='Europe/Moscow';
select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
master-bin.000001 # Query 1 # use `test`; create table t1 (t timestamp)
master-bin.000001 # Query 1 # use `test`; create table t2 (t char(32))
master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT TIME_ZONE='UTC'
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
master-bin.000001 # Query 1 # use `test`; delete from t1
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
use test;
SET TIMESTAMP=100000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
create table t1 (t timestamp);
SET TIMESTAMP=100000000;
create table t2 (t char(32));
SET TIMESTAMP=100000000;
SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20050101000000'), ('20050611093902');
SET TIMESTAMP=100000000;
SET @@session.time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
SET TIMESTAMP=100000000;
delete from t1;
SET TIMESTAMP=100000000;
SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
ROLLBACK;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
set time_zone='MET';
insert into t2 (select t from t1);
select * from t1;
@ -52,10 +78,6 @@ t
delete from t2;
set timestamp=1000072000;
insert into t2 values (current_timestamp), (current_date), (current_time);
set timestamp=1000072000;
select current_timestamp, current_date, current_time;
current_timestamp current_date current_time
2001-09-10 01:46:40 2001-09-10 01:46:40
select * from t2;
t
2001-09-09 23:46:40
@ -73,5 +95,16 @@ t
2001-09-09 03:46:40
1000000000
set global time_zone='MET';
ERROR HY000: Binary logging and replication forbid changing the global server time zone
delete from t2;
set time_zone='UTC';
insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone));
insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'));
select * from t2;
t
2003-12-31 23:00:00
2005-01-01 08:00:00
select * from t2;
t
2003-12-31 23:00:00
2005-01-01 08:00:00
drop table t1, t2;

View file

@ -315,57 +315,57 @@ insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1;
delete from t2;
delete from t3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t1 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 MEMORY 10 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3;
create database mysqltest;
show create database mysqltest;

View file

@ -149,7 +149,7 @@ v5 VIEW
v6 VIEW
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 9 Fixed 5 9 45 38654705663 1024 0 NULL # # NULL latin1_swedish_ci NULL
t1 MyISAM 10 Fixed 5 9 45 38654705663 1024 0 NULL # # NULL latin1_swedish_ci NULL
v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view
v2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view
v3 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view
@ -1115,7 +1115,7 @@ select * from v1;
ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s)
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 9 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
t1 MyISAM 10 Fixed 0 0 0 # 1024 0 NULL # # NULL latin1_swedish_ci NULL
v1 NULL NULL NULL NULL NULL NULL # NULL NULL NULL # # NULL NULL NULL NULL View 'test.v1' references invalid table(s) or column(s) or function(s)
drop view v1;
drop table t1;

View file

@ -179,7 +179,7 @@ show grants for 'mysqltest_1';
drop user 'mysqltest_1', 'mysqltest_3';
#
# Grant must not create user
--error 1211
--error 1410
grant all on test.t1 to 'mysqltest_1';
--error 1396
drop user 'mysqltest_1';

View file

@ -0,0 +1 @@
--safe-user-create

32
mysql-test/t/grant3.test Normal file
View file

@ -0,0 +1,32 @@
# Test of GRANT commands
SET NAMES binary;
connect (master,localhost,root,,);
connection master;
# Cleanup
--disable_warnings
drop table if exists t1;
--enable_warnings
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';
delete from mysql.columns_priv where user like 'mysqltest\_%';
flush privileges;
create user mysqltest_1@localhost;
grant grant option on mysql.* to mysqltest_1@localhost;
grant select on `my\_1`.* to mysqltest_1@localhost with grant option;
connect (user_a,localhost,mysqltest_1,,);
connection user_a;
--error 1410
grant select on `my\_1`.* to mysqltest_2@localhost;
disconnect user_a;
connection default;
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';
delete from mysql.columns_priv where user like 'mysqltest\_%';
flush privileges;

View file

@ -153,6 +153,13 @@ SELECT DISTINCT SUM(b), COUNT(DISTINCT b), COUNT(*) FROM t1
SELECT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
SELECT DISTINCT a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
SELECT b, a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
SELECT DISTINCT b,a, sum(b) FROM t1 GROUP BY a,b WITH ROLLUP;
ALTER TABLE t1 ADD COLUMN c INT;
SELECT a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP;
SELECT distinct a,b,sum(c) FROM t1 GROUP BY a,b,c WITH ROLLUP;
DROP TABLE t1;
#

View file

@ -1 +1 @@
--default-time-zone=Europe/Moscow
--default-time-zone=Japan

View file

@ -1,23 +1,38 @@
# Test of replication of time zones.
# There is currently some bug possibly in prepared statements (this
# test fails with --ps-protocol): sys_var_thd_time_zone::value_ptr()
# is called only at prepare time, not at execution time. So,
# thd->time_zone_used is not equal to 1 (it is back to 0, because of
# reset_thd_for_next_command called at execution time), so the
# timezone used in CONVERT_TZ is not binlogged. To debug (by Guilhem
# and possibly Konstantin).
--disable_ps_protocol
source include/master-slave.inc;
# Some preparations
let $VERSION=`select version()`;
set timestamp=100000000; # for fixed output of mysqlbinlog
create table t1 (t timestamp);
create table t2 (t char(32));
connection slave;
select @@time_zone;
#
# Let us check how well replication works when we are saving datetime
# value in TIMESTAMP field.
#
connection master;
select @@time_zone;
insert into t1 values ('20050101000000'), ('20050611093902');
set time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
# On slave we still in 'Europe/Moscow' so we should see equivalent but
# textually different values.
sync_slave_with_master;
set time_zone='UTC';
select * from t1;
# Let us check also that setting of time_zone back to default also works
@ -28,12 +43,11 @@ set time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
sync_slave_with_master;
set time_zone='Europe/Moscow';
select * from t1;
connection master;
# We should not see SET ONE_SHOT time_zone before second insert
--replace_result $VERSION VERSION
--replace_column 2 # 5 #
show binlog events;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
#
# Now let us check how well we replicate statments reading TIMESTAMP fields
@ -54,10 +68,6 @@ delete from t2;
set timestamp=1000072000;
insert into t2 values (current_timestamp), (current_date), (current_time);
sync_slave_with_master;
# Values in ouput of these to queries should differ because we are in
# in 'MET' on master and in 'Europe/Moscow on slave...
set timestamp=1000072000;
select current_timestamp, current_date, current_time;
select * from t2;
#
@ -73,13 +83,24 @@ sync_slave_with_master;
select * from t2;
#
# Let us check that we are not allowing to set global time_zone with
# Let us check that we are allowing to set global time_zone with
# replication
#
connection master;
--error 1387
set global time_zone='MET';
#
# Let us see if CONVERT_TZ(@@time_zone) replicates
#
delete from t2;
set time_zone='UTC';
insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone));
insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'));
select * from t2;
sync_slave_with_master;
select * from t2;
# Clean up
connection master;
drop table t1, t2;
sync_slave_with_master;

View file

@ -131,8 +131,8 @@ print "USE mysql_help;\n";
print "DROP TABLE IF EXISTS function;\n";
print "CREATE TABLE function (";
print " func_id int unsigned not null auto_increment,";
print " name varchar(64) not null,";
print " url varchar(128) not null,";
print " name char(64) not null,";
print " url char(128) not null,";
print " description text not null,";
print " example text not null,";
print " min_args tinyint not null,";
@ -145,8 +145,8 @@ print ") type=myisam;\n\n";
print "DROP TABLE IF EXISTS function_category_name;\n";
print "CREATE TABLE function_category_name (";
print " cat_id smallint unsigned not null auto_increment,";
print " name varchar(64) not null,";
print " url varchar(128) not null,";
print " name char(64) not null,";
print " url char(128) not null,";
print " date_created datetime not null,";
print " last_modified timestamp not null,";
print " primary key (cat_id)";

View file

@ -269,11 +269,11 @@ then
c_ht="$c_ht CREATE TABLE help_topic ("
c_ht="$c_ht help_topic_id int unsigned not null,"
c_ht="$c_ht name varchar(64) not null,"
c_ht="$c_ht name char(64) not null,"
c_ht="$c_ht help_category_id smallint unsigned not null,"
c_ht="$c_ht description text not null,"
c_ht="$c_ht example text not null,"
c_ht="$c_ht url varchar(128) not null,"
c_ht="$c_ht url char(128) not null,"
c_ht="$c_ht primary key (help_topic_id),"
c_ht="$c_ht unique index (name)"
c_ht="$c_ht ) engine=MyISAM"
@ -291,9 +291,9 @@ then
c_hc="$c_hc CREATE TABLE help_category ("
c_hc="$c_hc help_category_id smallint unsigned not null,"
c_hc="$c_hc name varchar(64) not null,"
c_hc="$c_hc name char(64) not null,"
c_hc="$c_hc parent_category_id smallint unsigned null,"
c_hc="$c_hc url varchar(128) not null,"
c_hc="$c_hc url char(128) not null,"
c_hc="$c_hc primary key (help_category_id),"
c_hc="$c_hc unique index (name)"
c_hc="$c_hc ) engine=MyISAM"
@ -309,7 +309,7 @@ then
c_hk="$c_hk CREATE TABLE help_keyword ("
c_hk="$c_hk help_keyword_id int unsigned not null,"
c_hk="$c_hk name varchar(64) not null,"
c_hk="$c_hk name char(64) not null,"
c_hk="$c_hk primary key (help_keyword_id),"
c_hk="$c_hk unique index (name)"
c_hk="$c_hk ) engine=MyISAM"

View file

@ -13,7 +13,7 @@ args=""
port=""
socket=""
database="mysql"
bindir="."
bindir=""
pkgdatadir="@pkgdatadir@"
print_defaults_bindir="."

View file

@ -307,19 +307,19 @@ KEY Grantor (Grantor)
CREATE TABLE IF NOT EXISTS help_topic (
help_topic_id int unsigned not null,
name varchar(64) not null,
name char(64) not null,
help_category_id smallint unsigned not null,
description text not null,
example text not null,
url varchar(128) not null,
url char(128) not null,
primary key (help_topic_id), unique index (name)
) CHARACTER SET utf8 comment='help topics';
CREATE TABLE IF NOT EXISTS help_category (
help_category_id smallint unsigned not null,
name varchar(64) not null,
name char(64) not null,
parent_category_id smallint unsigned null,
url varchar(128) not null,
url char(128) not null,
primary key (help_category_id),
unique index (name)
) CHARACTER SET utf8 comment='help categories';
@ -332,7 +332,7 @@ primary key (help_keyword_id, help_topic_id)
CREATE TABLE IF NOT EXISTS help_keyword (
help_keyword_id int unsigned not null,
name varchar(64) not null,
name char(64) not null,
primary key (help_keyword_id),
unique index (name)
) CHARACTER SET utf8 comment='help keywords';
@ -479,3 +479,35 @@ ALTER TABLE proc MODIFY name char(64) DEFAULT '' NOT NULL,
'NO_AUTO_CREATE_USER',
'HIGH_NOT_PRECEDENCE'
) DEFAULT 0 NOT NULL;
#
# Change all varchar fields in privilege tables to CHAR, to ensure that
# we can use the privilege tables in MySQL 4.1
# Note that for this hack to work, we must change all CHAR() columns at
# the same time
#
ALTER TABLE mysql.user
modify Host char(60) binary DEFAULT '' NOT NULL,
modify User char(16) binary DEFAULT '' NOT NULL,
modify Password char(41) binary DEFAULT '' NOT NULL;
ALTER TABLE mysql.db
modify Host char(60) binary DEFAULT '' NOT NULL,
modify Db char(64) binary DEFAULT '' NOT NULL,
modify User char(16) binary DEFAULT '' NOT NULL;
ALTER TABLE mysql.host
modify Host char(60) binary DEFAULT '' NOT NULL,
modify Db char(64) binary DEFAULT '' NOT NULL;
ALTER TABLE help_topic
modify name char(64) not null,
modify url char(128) not null;
ALTER TABLE help_category
modify name char(64) not null,
modify url char(128) not null;
ALTER TABLE help_keyword
modify name char(64) not null;

View file

@ -14,14 +14,17 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "command.h"
#include "commands.h"
#include "instance.h"
#include "instance_map.h"
#include "messages.h"
#include "mysqld_error.h"
#include "mysql_manager_error.h"
#include "protocol.h"
#include "buffer.h"
#include <m_string.h>
#include <mysql.h>
/* implementation for Show_instances: */

View file

@ -16,8 +16,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "command.h"
#include "instance.h"
#include "my_global.h"
/*
Print all instances of this instance manager.

View file

@ -15,11 +15,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "factory.h"
#include "my_global.h"
#include <stdio.h>
#include <ctype.h>
Show_instances *Command_factory::new_Show_instances()
{

View file

@ -20,10 +20,12 @@
#endif
#include "guardian.h"
#include "instance_map.h"
#include "instance.h"
#include "mysql_manager_error.h"
#include "log.h"
#include <string.h>
#include <sys/types.h>
#include <signal.h>

View file

@ -17,9 +17,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "thread_registry.h"
#include <my_sys.h>
#include <my_list.h>
#include "thread_registry.h"
#ifdef __GNUC__
#pragma interface

View file

@ -19,16 +19,17 @@
#endif
#include "instance.h"
#include "mysql_manager_error.h"
#include "log.h"
#include "instance_map.h"
#include "priv.h"
#include <sys/wait.h>
#include <my_sys.h>
#include <signal.h>
#include <m_string.h>
#include <sys/wait.h>
#include <mysql.h>
C_MODE_START

View file

@ -17,8 +17,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include <mysql.h>
#include "instance_options.h"
#ifdef __GNUC__

View file

@ -19,10 +19,11 @@
#endif
#include "instance_map.h"
#include "buffer.h"
#include "instance.h"
#include <m_ctype.h>
#include <my_sys.h>
#include <mysql_com.h>
#include <m_string.h>

View file

@ -17,6 +17,10 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "protocol.h"
#include "guardian.h"
#include <my_sys.h>
#include <hash.h>
@ -24,9 +28,6 @@
#pragma interface
#endif
#include "protocol.h"
#include "guardian.h"
class Instance;
extern int load_all_groups(char ***groups, const char *filename);
extern void free_groups(char **groups);

View file

@ -19,8 +19,10 @@
#endif
#include "instance_options.h"
#include "parse_output.h"
#include "buffer.h"
#include <my_sys.h>
#include <mysql.h>
#include <signal.h>

View file

@ -14,8 +14,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "log.h"
#include <my_global.h>
#include "log.h"
#include <stdarg.h>
#include <m_string.h>
#include <my_sys.h>

View file

@ -14,6 +14,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "manager.h"
#include "priv.h"
@ -25,7 +26,6 @@
#include "log.h"
#include "guardian.h"
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <signal.h>

View file

@ -13,11 +13,14 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "messages.h"
#include <my_global.h>
#include <mysql_com.h>
#include "messages.h"
#include "mysqld_error.h"
#include "mysql_manager_error.h"
#include <mysql_com.h>
#include <assert.h>

View file

@ -16,9 +16,6 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysqld_error.h"
#include "mysql_manager_error.h"
const char *message(unsigned sql_errno);
const char *errno_to_sqlstate(unsigned sql_errno);

View file

@ -19,14 +19,10 @@
#endif
#include "mysql_connection.h"
#include "priv.h"
#include <mysql.h>
#include <violite.h>
#include <mysql_com.h>
#include <m_string.h>
#include <my_sys.h>
#include "mysql_manager_error.h"
#include "mysqld_error.h"
#include "thread_registry.h"
#include "log.h"
#include "user_map.h"
@ -36,6 +32,13 @@
#include "factory.h"
#include "parse.h"
#include <mysql.h>
#include <violite.h>
#include <mysql_com.h>
#include <m_string.h>
#include <my_sys.h>
Command *parse_command(Command_factory * factory, const char *text);
Mysql_connection_thread_args::Mysql_connection_thread_args(

View file

@ -14,11 +14,12 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "manager.h"
#include "options.h"
#include "log.h"
#include <my_global.h>
#include <my_sys.h>
#include <string.h>
#include <signal.h>

View file

@ -20,14 +20,13 @@
#include "options.h"
#include <my_global.h>
#include "priv.h"
#include <my_sys.h>
#include <my_getopt.h>
#include <m_string.h>
#include <mysql_com.h>
#include "priv.h"
#define QUOTE2(x) #x
#define QUOTE(x) QUOTE2(x)

View file

@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "parse.h"
#include <string.h>
enum Token

View file

@ -14,10 +14,10 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "parse.h"
#include <stdio.h>
#include <my_global.h>
#include <my_sys.h>
#include <string.h>

View file

@ -14,13 +14,13 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include <my_sys.h>
#include "protocol.h"
#include "messages.h"
#include <mysql_com.h>
#include <m_string.h>
#include "messages.h"
#include "protocol.h"
static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */

View file

@ -17,6 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "buffer.h"
#include <my_list.h>
typedef struct field {

View file

@ -20,10 +20,11 @@
#include "thread_registry.h"
#include "log.h"
#include <assert.h>
#include <signal.h>
#include <thr_alarm.h>
#include "log.h"
/* Kick-off signal handler */

View file

@ -17,10 +17,11 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma interface
#pragma interface
#endif
#include <my_global.h>
#include <my_sys.h>
#include <hash.h>

View file

@ -1309,6 +1309,9 @@ innobase_end(void)
}
#endif
if (innodb_inited) {
#ifndef __NETWARE__ /* NetWare can't close unclosed files, kill remaining
threads, etc, so we disable the very fast shutdown */
if (innobase_very_fast_shutdown) {
srv_very_fast_shutdown = TRUE;
fprintf(stderr,
@ -1316,6 +1319,7 @@ innobase_end(void)
"InnoDB: the InnoDB buffer pool to data files. At the next mysqld startup\n"
"InnoDB: InnoDB will do a crash recovery!\n");
}
#endif
innodb_inited = 0;
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {

View file

@ -764,14 +764,13 @@ static char* xid_to_str(char *buf, XID *xid)
for (i=0; i < xid->gtrid_length+xid->bqual_length; i++)
{
uchar c=(uchar)xid->data[i];
bool is_next_dig;
/* is_next_dig is set if next character is a number */
bool is_next_dig= FALSE;
if (i < XIDDATASIZE)
{
char ch=xid->data[i+1];
is_next_dig=(c >= '0' && c <='9');
char ch= xid->data[i+1];
is_next_dig= (ch >= '0' && ch <='9');
}
else
is_next_dig=FALSE;
if (i == xid->gtrid_length)
{
*s++='\'';
@ -784,6 +783,11 @@ static char* xid_to_str(char *buf, XID *xid)
if (c < 32 || c > 126)
{
*s++='\\';
/*
If next character is a number, write current character with
3 octal numbers to ensure that the next number is not seen
as part of the octal number
*/
if (c > 077 || is_next_dig)
*s++=_dig_vec_lower[c >> 6];
if (c > 007 || is_next_dig)

View file

@ -586,18 +586,8 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
return NULL;
}
conv->str_value.copy();
/*
The above line executes str_value.realloc() internally,
which alligns Alloced_length using ALLIGN_SIZE.
In the case of Item_string::str_value we don't want
Alloced_length to be longer than str_length.
Otherwise, some functions like Item_func_concat::val_str()
try to reuse str_value as a buffer for concatenation result
for optimization purposes, so our string constant become
corrupted. See bug#8785 for more details.
Let's shrink Alloced_length to str_length to avoid this problem.
*/
conv->str_value.shrink_to_length();
/* Ensure that no one is going to change the result string */
conv->str_value.mark_as_const();
return conv;
}

View file

@ -2158,7 +2158,7 @@ int composite_key_cmp(void* arg, byte* key1, byte* key2)
}
static int count_distinct_walk(void *elem, unsigned int count, void *arg)
static int count_distinct_walk(void *elem, element_count count, void *arg)
{
(*((ulonglong*)arg))++;
return 0;
@ -2667,11 +2667,11 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
TABLE *table= item->table;
char *record= (char*) table->record[0] + table->s->null_bytes;
String tmp(table->record[1], table->s->reclength, default_charset_info), tmp2;
String &result= item->result;
String *result= &item->result;
Item **arg= item->args, **arg_end= item->args + item->arg_count_field;
if (result.length())
result.append(*item->separator);
if (result->length())
result->append(*item->separator);
tmp.length(0);
@ -2698,14 +2698,14 @@ int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
else
res= (*arg)->val_str(&tmp);
if (res)
result.append(*res);
result->append(*res);
}
/* stop if length of result more than max_length */
if (result.length() > item->max_length)
if (result->length() > item->max_length)
{
item->count_cut_values++;
result.length(item->max_length);
result->length(item->max_length);
item->warning_for_row= TRUE;
return 1;
}
@ -2906,8 +2906,6 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
MYF(0));
return TRUE;
}
if (!args) /* allocation in constructor may fail */
return TRUE;
thd->allow_sum_func= 0;
maybe_null= 0;
@ -2968,12 +2966,10 @@ bool Item_func_group_concat::setup(THD *thd)
if (item->null_value)
{
always_null= 1;
break;
DBUG_RETURN(FALSE);
}
}
}
if (always_null)
DBUG_RETURN(FALSE);
List<Item> all_fields(list);
/*

View file

@ -1638,57 +1638,6 @@ bool MYSQL_LOG::write(Log_event *event_info)
if (thd)
{
#if MYSQL_VERSION_ID < 50003
/*
To make replication of charsets working in 4.1 we are writing values
of charset related variables before every statement in the binlog,
if values of those variables differ from global server-wide defaults.
We are using SET ONE_SHOT command so that the charset vars get reset
to default after the first non-SET statement.
In the next 5.0 this won't be needed as we will use the new binlog
format to store charset info.
*/
if ((thd->variables.character_set_client->number !=
global_system_variables.collation_server->number) ||
(thd->variables.character_set_client->number !=
thd->variables.collation_connection->number) ||
(thd->variables.collation_server->number !=
thd->variables.collation_connection->number))
{
char buf[200];
int written= my_snprintf(buf, sizeof(buf)-1,
"SET ONE_SHOT CHARACTER_SET_CLIENT=%u,\
COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
(uint) thd->variables.character_set_client->number,
(uint) thd->variables.collation_connection->number,
(uint) thd->variables.collation_database->number,
(uint) thd->variables.collation_server->number);
Query_log_event e(thd, buf, written, 0, FALSE);
if (e.write(file))
goto err;
}
#endif
/*
We use the same ONE_SHOT trick for making replication of time zones
working in 4.1. Again in 5.0 we have better means for doing this.
TODO: we should do like we now do with charsets (no more ONE_SHOT;
logging in each event in a compact format). Dmitri says we can do:
if (time_zone_used) write the timezone to binlog (in a format to be
defined).
*/
if (thd->time_zone_used &&
thd->variables.time_zone != global_system_variables.time_zone)
{
char buf[MAX_TIME_ZONE_NAME_LENGTH + 26];
char *buf_end= strxmov(buf, "SET ONE_SHOT TIME_ZONE='",
thd->variables.time_zone->get_name()->ptr(),
"'", NullS);
Query_log_event e(thd, buf, buf_end - buf, 0, FALSE);
if (e.write(file))
goto err;
}
if (thd->last_insert_id_used)
{
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,

View file

@ -506,8 +506,6 @@ void Log_event::init_show_field_list(List<Item>* field_list)
field_list->push_back(new Item_empty_string("Info", 20));
}
#endif /* !MYSQL_CLIENT */
/*
Log_event::write()
@ -592,7 +590,6 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
*/
#ifndef MYSQL_CLIENT
int Log_event::read_log_event(IO_CACHE* file, String* packet,
pthread_mutex_t* log_lock)
{
@ -956,6 +953,7 @@ void Query_log_event::pack_info(Protocol *protocol)
}
#endif
#ifndef MYSQL_CLIENT
/*
Query_log_event::write()
@ -973,7 +971,8 @@ bool Query_log_event::write(IO_CACHE* file)
1+8+ // code of sql_mode and sql_mode
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1+4+ // code of autoinc and the 2 autoinc variables
1+6 // code of charset and charset
1+6+ // code of charset and charset
1+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name
], *start, *start_of_status;
ulong event_length;
@ -1030,20 +1029,20 @@ bool Query_log_event::write(IO_CACHE* file)
start_of_status= start= buf+QUERY_HEADER_LEN;
if (flags2_inited)
{
*(start++)= Q_FLAGS2_CODE;
*start++= Q_FLAGS2_CODE;
int4store(start, flags2);
start+= 4;
}
if (sql_mode_inited)
{
*(start++)= Q_SQL_MODE_CODE;
*start++= Q_SQL_MODE_CODE;
int8store(start, (ulonglong)sql_mode);
start+= 8;
}
if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events)
if (catalog_len) // i.e. "catalog inited" (false for 4.0 events)
{
*(start++)= Q_CATALOG_CODE;
*(start++)= (uchar) catalog_len;
*start++= Q_CATALOG_CODE;
*start++= (uchar) catalog_len;
bmove(start, catalog, catalog_len);
start+= catalog_len;
/*
@ -1071,15 +1070,24 @@ bool Query_log_event::write(IO_CACHE* file)
}
if (charset_inited)
{
*(start++)= Q_CHARSET_CODE;
*start++= Q_CHARSET_CODE;
memcpy(start, charset, 6);
start+= 6;
}
if (time_zone_len)
{
/* In the TZ sys table, column Name is of length 64 so this should be ok */
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
*start++= Q_TIME_ZONE_CODE;
*start++= time_zone_len;
memcpy(start, time_zone_str, time_zone_len);
start+= time_zone_len;
}
/*
Here there could be code like
if (command-line-option-which-says-"log_this_variable" && inited)
{
*(start++)= Q_THIS_VARIABLE_CODE;
*start++= Q_THIS_VARIABLE_CODE;
int4store(start, this_variable);
start+= 4;
}
@ -1108,8 +1116,6 @@ bool Query_log_event::write(IO_CACHE* file)
/*
Query_log_event::Query_log_event()
*/
#ifndef MYSQL_CLIENT
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans,
bool suppress_use)
@ -1150,6 +1156,18 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
int2store(charset, thd_arg->variables.character_set_client->number);
int2store(charset+2, thd_arg->variables.collation_connection->number);
int2store(charset+4, thd_arg->variables.collation_server->number);
if (thd_arg->time_zone_used)
{
/*
Note that our event becomes dependent on the Time_zone object
representing the time zone. Fortunately such objects are never deleted
or changed during mysqld's lifetime.
*/
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
}
else
time_zone_len= 0;
DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
}
#endif /* MYSQL_CLIENT */
@ -1163,15 +1181,17 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
Query_log_event::Query_log_event(const char* buf, uint event_len,
const Format_description_log_event *description_event,
Log_event_type event_type)
:Log_event(buf, description_event), data_buf(0), query(NullS), catalog(NullS),
:Log_event(buf, description_event), data_buf(0), query(NullS),
db(NullS), catalog_len(0), status_vars_len(0),
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
auto_increment_increment(1), auto_increment_offset(1)
auto_increment_increment(1), auto_increment_offset(1),
time_zone_len(0)
{
ulong data_len;
uint32 tmp;
uint8 common_header_len, post_header_len;
const char *start, *end;
char *start;
const char *end;
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
common_header_len= description_event->common_header_len;
@ -1191,7 +1211,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
db_len = (uint)buf[Q_DB_LEN_OFFSET];
db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
/*
@ -1217,7 +1237,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
/* variable-part: the status vars; only in MySQL 5.0 */
start= (char*) (buf+post_header_len);
end= (char*) (start+status_vars_len);
end= (const char*) (start+status_vars_len);
for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
{
switch (*pos++) {
@ -1240,8 +1260,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
break;
}
case Q_CATALOG_CODE:
catalog_len= *pos;
if (catalog_len)
if ((catalog_len= *pos))
catalog= (char*) pos+1; // Will be copied later
pos+= catalog_len+2;
break;
@ -1257,6 +1276,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
pos+= 6;
break;
}
case Q_TIME_ZONE_CODE:
{
if ((time_zone_len= *pos))
time_zone_str= (char *)(pos+1);
pos+= time_zone_len+1;
break;
}
default:
/* That's why you must write status vars in growing order of code */
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
@ -1265,24 +1291,29 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
}
/* A 2nd variable part; this is common to all versions */
if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME))))
if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
time_zone_len + 1 +
data_len + 1, MYF(MY_WME))))
DBUG_VOID_RETURN;
if (catalog) // If catalog is given
if (catalog_len) // If catalog is given
{
memcpy((char*) start, catalog, catalog_len+1); // Copy name and end \0
memcpy(start, catalog, catalog_len+1); // Copy name and end \0
catalog= start;
start+= catalog_len+1;
}
if (time_zone_len)
{
memcpy(start, time_zone_str, time_zone_len);
time_zone_str= start;
start+= time_zone_len;
*start++= 0;
}
/* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
((char*) start)[data_len]= '\0'; // End query with \0 (For safetly)
start[data_len]= '\0'; // End query with \0 (For safetly)
db= start;
query= start + db_len + 1;
q_len= data_len - db_len -1;
/* This is used to detect wrong parsing. Could be removed in the future. */
DBUG_PRINT("info", ("catalog: '%s' len: %u db: '%s' len: %u q_len: %lu",
catalog, (uint) catalog_len, db, (uint) db_len,q_len));
DBUG_VOID_RETURN;
}
@ -1390,6 +1421,8 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
last_event_info->auto_increment_offset= auto_increment_offset;
}
/* TODO: print the catalog when we feature SET CATALOG */
if (likely(charset_inited))
{
if (unlikely(!last_event_info->charset_inited)) /* first Query event */
@ -1410,6 +1443,14 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
memcpy(last_event_info->charset, charset, 6);
}
}
if (time_zone_len)
{
if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
{
fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
}
}
}
@ -1443,7 +1484,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
alloced block (see Query_log_event::exec_event()). Same for thd->db.
Thank you.
*/
thd->catalog= (char*) catalog;
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
thd->db_length= db_len;
thd->db= (char*) rewrite_db(db, &thd->db_length);
thd->variables.auto_increment_increment= auto_increment_increment;
@ -1513,20 +1554,28 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
get_charset(uint2korr(charset+4), MYF(MY_WME))))
{
/*
We updated the thd->variables with nonsensical values (0), and the
thread is not guaranteed to terminate now (as it may be configured
to ignore EE_UNKNOWN_CHARSET);if we're going to execute a next
statement we'll have a new charset info with it, so no problem to
have stored 0 in thd->variables. But we invalidate cached
charset to force a check next time (otherwise if next time
charset is unknown again we won't detect it).
We updated the thd->variables with nonsensical values (0). Let's
set them to something safe (i.e. which avoids crash), and we'll
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
ignore this error).
*/
rli->cached_charset_invalidate();
set_slave_thread_default_charset(thd, rli);
goto compare_errors;
}
thd->update_charset(); // for the charset change to take effect
}
}
if (time_zone_len)
{
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
if (!(thd->variables.time_zone=
my_tz_find_with_opening_tz_tables(thd, &tmp)))
{
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
thd->variables.time_zone= global_system_variables.time_zone;
goto compare_errors;
}
}
/* Execute the query (note that we bypass dispatch_command()) */
mysql_parse(thd, thd->query, thd->query_length);
@ -1751,6 +1800,7 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
Start_log_event_v3::write()
*/
#ifndef MYSQL_CLIENT
bool Start_log_event_v3::write(IO_CACHE* file)
{
char buff[START_V3_HEADER_LEN];
@ -1760,6 +1810,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, (byte*) buff, sizeof(buff)));
}
#endif
/*
@ -1975,7 +2026,7 @@ Format_description_log_event(const char* buf,
DBUG_VOID_RETURN;
}
#ifndef MYSQL_CLIENT
bool Format_description_log_event::write(IO_CACHE* file)
{
/*
@ -1992,6 +2043,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buff)) ||
my_b_safe_write(file, buff, sizeof(buff)));
}
#endif
/*
SYNOPSIS
@ -2210,6 +2262,8 @@ void Load_log_event::pack_info(Protocol *protocol)
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
#ifndef MYSQL_CLIENT
/*
Load_log_event::write_data_header()
*/
@ -2251,7 +2305,6 @@ bool Load_log_event::write_data_body(IO_CACHE* file)
Load_log_event::Load_log_event()
*/
#ifndef MYSQL_CLIENT
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
const char *db_arg, const char *table_name_arg,
List<Item> &fields_arg,
@ -2865,6 +2918,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
Rotate_log_event::write()
*/
#ifndef MYSQL_CLIENT
bool Rotate_log_event::write(IO_CACHE* file)
{
char buf[ROTATE_HEADER_LEN];
@ -2873,7 +2927,7 @@ bool Rotate_log_event::write(IO_CACHE* file)
my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
}
#endif
/*
Rotate_log_event::exec_event()
@ -2931,17 +2985,10 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
master is 4.0 then the events are in the slave's format (conversion).
*/
set_slave_thread_options(thd);
set_slave_thread_default_charset(thd, rli);
thd->variables.sql_mode= global_system_variables.sql_mode;
thd->variables.auto_increment_increment=
thd->variables.auto_increment_offset= 1;
thd->variables.character_set_client=
global_system_variables.character_set_client;
thd->variables.collation_connection=
global_system_variables.collation_connection;
thd->variables.collation_server=
global_system_variables.collation_server;
thd->update_charset();
rli->cached_charset_invalidate();
}
pthread_mutex_unlock(&rli->data_lock);
pthread_cond_broadcast(&rli->data_cond);
@ -3003,6 +3050,7 @@ const char* Intvar_log_event::get_var_type_name()
Intvar_log_event::write()
*/
#ifndef MYSQL_CLIENT
bool Intvar_log_event::write(IO_CACHE* file)
{
byte buf[9];
@ -3011,6 +3059,7 @@ bool Intvar_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
#endif
/*
@ -3095,6 +3144,7 @@ Rand_log_event::Rand_log_event(const char* buf,
}
#ifndef MYSQL_CLIENT
bool Rand_log_event::write(IO_CACHE* file)
{
byte buf[16];
@ -3103,6 +3153,7 @@ bool Rand_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
#endif
#ifdef MYSQL_CLIENT
@ -3166,11 +3217,13 @@ Xid_log_event(const char* buf,
}
#ifndef MYSQL_CLIENT
bool Xid_log_event::write(IO_CACHE* file)
{
return write_header(file, sizeof(xid)) ||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
}
#endif
#ifdef MYSQL_CLIENT
@ -3304,6 +3357,7 @@ User_var_log_event(const char* buf,
}
#ifndef MYSQL_CLIENT
bool User_var_log_event::write(IO_CACHE* file)
{
char buf[UV_NAME_LEN_SIZE];
@ -3338,7 +3392,7 @@ bool User_var_log_event::write(IO_CACHE* file)
dec->fix_buffer_pointer();
buf2[0]= (char)(dec->intg + dec->frac);
buf2[1]= (char)dec->frac;
decimal2bin((decimal*)val, buf2+2, buf2[0], buf2[1]);
decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
break;
}
@ -3363,6 +3417,7 @@ bool User_var_log_event::write(IO_CACHE* file)
my_b_safe_write(file, (byte*) buf1, buf1_length) ||
my_b_safe_write(file, (byte*) pos, val_len));
}
#endif
/*
@ -3405,8 +3460,8 @@ void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* las
int str_len= sizeof(str_buf) - 1;
int precision= (int)val[0];
int scale= (int)val[1];
decimal_digit dec_buf[10];
decimal dec;
decimal_digit_t dec_buf[10];
decimal_t dec;
dec.len= 10;
dec.buf= dec_buf;
@ -3636,6 +3691,7 @@ int Slave_log_event::get_data_size()
}
#ifndef MYSQL_CLIENT
bool Slave_log_event::write(IO_CACHE* file)
{
ulong event_length= get_data_size();
@ -3646,6 +3702,7 @@ bool Slave_log_event::write(IO_CACHE* file)
return (write_header(file, event_length) ||
my_b_safe_write(file, (byte*) mem_pool, event_length));
}
#endif
void Slave_log_event::init_from_mem_pool(int data_size)
@ -3772,7 +3829,6 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex,
sql_ex.force_new_format();
DBUG_VOID_RETURN;
}
#endif /* !MYSQL_CLIENT */
/*
@ -3817,6 +3873,7 @@ bool Create_file_log_event::write_base(IO_CACHE* file)
return res;
}
#endif /* !MYSQL_CLIENT */
/*
Create_file_log_event ctor
@ -4044,6 +4101,7 @@ Append_block_log_event::Append_block_log_event(const char* buf, uint len,
Append_block_log_event::write()
*/
#ifndef MYSQL_CLIENT
bool Append_block_log_event::write(IO_CACHE* file)
{
byte buf[APPEND_BLOCK_HEADER_LEN];
@ -4052,6 +4110,7 @@ bool Append_block_log_event::write(IO_CACHE* file)
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
my_b_safe_write(file, (byte*) block, block_len));
}
#endif
/*
@ -4173,6 +4232,7 @@ Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
Delete_file_log_event::write()
*/
#ifndef MYSQL_CLIENT
bool Delete_file_log_event::write(IO_CACHE* file)
{
byte buf[DELETE_FILE_HEADER_LEN];
@ -4180,6 +4240,7 @@ bool Delete_file_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
#endif
/*
@ -4267,6 +4328,7 @@ Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
Execute_load_log_event::write()
*/
#ifndef MYSQL_CLIENT
bool Execute_load_log_event::write(IO_CACHE* file)
{
byte buf[EXEC_LOAD_HEADER_LEN];
@ -4274,6 +4336,7 @@ bool Execute_load_log_event::write(IO_CACHE* file)
return (write_header(file, sizeof(buf)) ||
my_b_safe_write(file, buf, sizeof(buf)));
}
#endif
/*
@ -4477,6 +4540,7 @@ ulong Execute_load_query_log_event::get_post_header_size_for_derived()
}
#ifndef MYSQL_CLIENT
bool
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
{
@ -4487,6 +4551,7 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
*(buf + 4 + 4 + 4)= (char)dup_handling;
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
}
#endif
#ifdef MYSQL_CLIENT

View file

@ -237,6 +237,7 @@ struct sql_ex_info
#define Q_CATALOG_CODE 2
#define Q_AUTO_INCREMENT 3
#define Q_CHARSET_CODE 4
#define Q_TIME_ZONE_CODE 5
/* Intvar event post-header */
@ -448,6 +449,7 @@ typedef struct st_last_event_info
ulong auto_increment_increment, auto_increment_offset;
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
st_last_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
@ -459,6 +461,7 @@ typedef struct st_last_event_info
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
}
} LAST_EVENT_INFO;
#endif
@ -583,6 +586,7 @@ public:
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
virtual bool write(IO_CACHE* file)
{
@ -590,13 +594,14 @@ public:
write_data_header(file) ||
write_data_body(file));
}
virtual bool is_artificial_event() { return 0; }
virtual bool write_data_header(IO_CACHE* file)
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
virtual bool is_artificial_event() { return 0; }
inline bool get_cache_stmt() { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event* description_event);
virtual ~Log_event() { free_temp_buf();}
@ -672,7 +677,7 @@ public:
concerned) from here.
*/
int catalog_len; // <= 255 char; -1 means uninited
uint catalog_len; // <= 255 char; 0 means uninited
/*
We want to be able to store a variable number of N-bit status vars:
@ -714,6 +719,8 @@ public:
ulong sql_mode;
ulong auto_increment_increment, auto_increment_offset;
char charset[6];
uint time_zone_len; /* 0 means uninited */
const char *time_zone_str;
#ifndef MYSQL_CLIENT
@ -737,12 +744,13 @@ public:
~Query_log_event()
{
if (data_buf)
{
my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return QUERY_EVENT; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
#endif
bool is_valid() const { return query != 0; }
/*
@ -751,7 +759,6 @@ public:
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
/* Writes derived event-specific part of post header. */
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
};
#ifdef HAVE_REPLICATION
@ -790,7 +797,9 @@ public:
int get_data_size();
bool is_valid() const { return master_host != 0; }
Log_event_type get_type_code() { return SLAVE_EVENT; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
};
#endif /* HAVE_REPLICATION */
@ -885,8 +894,10 @@ public:
{
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
}
#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
#endif
bool is_valid() const { return table_name != 0; }
int get_data_size()
{
@ -962,7 +973,9 @@ public:
const Format_description_log_event* description_event);
~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
int get_data_size()
{
@ -1004,7 +1017,9 @@ public:
const Format_description_log_event* description_event);
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
@ -1054,7 +1069,9 @@ public:
Log_event_type get_type_code() { return INTVAR_EVENT;}
const char* get_var_type_name();
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
@ -1092,7 +1109,9 @@ class Rand_log_event: public Log_event
~Rand_log_event() {}
Log_event_type get_type_code() { return RAND_EVENT;}
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
@ -1127,7 +1146,9 @@ class Xid_log_event: public Log_event
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
@ -1169,7 +1190,9 @@ public:
User_var_log_event(const char* buf, const Format_description_log_event* description_event);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
@ -1239,7 +1262,9 @@ public:
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
};
@ -1299,6 +1324,7 @@ public:
4 + 1 + block_len);
}
bool is_valid() const { return inited_from_old || block != 0; }
#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
/*
@ -1306,6 +1332,7 @@ public:
write it as Load event - used on the slave
*/
bool write_base(IO_CACHE* file);
#endif
};
@ -1352,7 +1379,9 @@ public:
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() const { return block != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
@ -1386,7 +1415,9 @@ public:
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
@ -1419,7 +1450,9 @@ public:
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
@ -1507,7 +1540,9 @@ public:
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
ulong get_post_header_size_for_derived();
#ifndef MYSQL_CLIENT
bool write_post_header_for_derived(IO_CACHE* file);
#endif
};

View file

@ -88,7 +88,7 @@ int my_decimal2string(uint mask, const my_decimal *d,
int result;
if (str->alloc(length))
return check_result(mask, E_DEC_OOM);
result= decimal2string((decimal*) d, (char*) str->ptr(),
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
&length, fixed_prec, fixed_dec,
filler);
str->length(length);
@ -172,7 +172,7 @@ int str2my_decimal(uint mask, const char *from, uint length,
charset= &my_charset_bin;
}
from_end= end= (char*) from+length;
err= string2decimal((char *)from, (decimal *)decimal_value, &end);
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
if (end != from_end && !err)
{
/* Give warining if there is something other than end space */

View file

@ -69,15 +69,15 @@ inline uint my_decimal_size(uint precision, uint scale)
/*
my_decimal class limits 'decimal' type to what we need in MySQL
my_decimal class limits 'decimal_t' type to what we need in MySQL
It contains internally all necessary space needed by the instance so
no extra memory is needed. One should call fix_buffer_pointer() function
when he moves my_decimal objects in memory
*/
class my_decimal :public decimal
class my_decimal :public decimal_t
{
decimal_digit buffer[DECIMAL_BUFF_LENGTH];
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
public:
@ -97,8 +97,8 @@ public:
}
void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal::sign; }
void sign(bool s) { decimal::sign= s; }
bool sign() const { return decimal_t::sign; }
void sign(bool s) { decimal_t::sign= s; }
};
@ -165,7 +165,7 @@ inline
int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec,
int scale)
{
return check_result(mask, bin2decimal((char *)bin, (decimal*) d, prec,
return check_result(mask, bin2decimal((char *)bin, (decimal_t*) d, prec,
scale));
}
@ -173,7 +173,7 @@ int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec,
inline
int my_decimal_set_zero(my_decimal *d)
{
decimal_make_zero(((decimal*) d));
decimal_make_zero(((decimal_t*) d));
return 0;
}
@ -181,7 +181,7 @@ int my_decimal_set_zero(my_decimal *d)
inline
bool my_decimal_is_zero(const my_decimal *decimal_value)
{
return decimal_is_zero((decimal*) decimal_value);
return decimal_is_zero((decimal_t*) decimal_value);
}
@ -189,7 +189,7 @@ inline
int my_decimal_round(uint mask, const my_decimal *from, int scale,
bool truncate, my_decimal *to)
{
return check_result(mask, decimal_round((decimal*) from, to, scale,
return check_result(mask, decimal_round((decimal_t*) from, to, scale,
(truncate ? TRUNCATE : HALF_UP)));
}
@ -197,14 +197,14 @@ int my_decimal_round(uint mask, const my_decimal *from, int scale,
inline
int my_decimal_floor(uint mask, const my_decimal *from, my_decimal *to)
{
return check_result(mask, decimal_round((decimal*) from, to, 0, FLOOR));
return check_result(mask, decimal_round((decimal_t*) from, to, 0, FLOOR));
}
inline
int my_decimal_ceiling(uint mask, const my_decimal *from, my_decimal *to)
{
return check_result(mask, decimal_round((decimal*) from, to, 0, CEILING));
return check_result(mask, decimal_round((decimal_t*) from, to, 0, CEILING));
}
@ -219,7 +219,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag,
{
my_decimal rounded;
/* decimal_round can return only E_DEC_TRUNCATED */
decimal_round((decimal*)d, &rounded, 0, HALF_UP);
decimal_round((decimal_t*)d, &rounded, 0, HALF_UP);
return check_result(mask, (unsigned_flag ?
decimal2ulonglong(&rounded, (ulonglong *)l) :
decimal2longlong(&rounded, l)));
@ -230,14 +230,14 @@ inline
int my_decimal2double(uint mask, const my_decimal *d, double *result)
{
/* No need to call check_result as this will always succeed */
return decimal2double((decimal*) d, result);
return decimal2double((decimal_t*) d, result);
}
inline
int str2my_decimal(uint mask, const char *str, my_decimal *d, char **end)
{
return check_result(mask, string2decimal(str, (decimal*) d, end));
return check_result(mask, string2decimal(str, (decimal_t*) d, end));
}
@ -255,7 +255,7 @@ int string2my_decimal(uint mask, const String *str, my_decimal *d)
inline
int double2my_decimal(uint mask, double val, my_decimal *d)
{
return check_result(mask, double2decimal(val, (decimal*) d));
return check_result(mask, double2decimal(val, (decimal_t*) d));
}
@ -269,7 +269,7 @@ int int2my_decimal(uint mask, longlong i, my_bool unsigned_flag, my_decimal *d)
inline
void my_decimal_neg(st_decimal *arg)
void my_decimal_neg(decimal_t *arg)
{
decimal_neg(arg);
}
@ -279,7 +279,7 @@ inline
int my_decimal_add(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
return check_result(mask, decimal_add((decimal*) a, (decimal*) b, res));
return check_result(mask, decimal_add((decimal_t*) a, (decimal_t*) b, res));
}
@ -287,7 +287,7 @@ inline
int my_decimal_sub(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
return check_result(mask, decimal_sub((decimal*) a, (decimal*) b, res));
return check_result(mask, decimal_sub((decimal_t*) a, (decimal_t*) b, res));
}
@ -295,7 +295,7 @@ inline
int my_decimal_mul(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
return check_result(mask, decimal_mul((decimal*) a, (decimal*) b, res));
return check_result(mask, decimal_mul((decimal_t*) a, (decimal_t*) b, res));
}
@ -303,7 +303,7 @@ inline
int my_decimal_div(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b, int div_scale_inc)
{
return check_result(mask, decimal_div((decimal*) a, (decimal*) b, res,
return check_result(mask, decimal_div((decimal_t*) a, (decimal_t*) b, res,
div_scale_inc));
}
@ -312,7 +312,7 @@ inline
int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
const my_decimal *b)
{
return check_result(mask, decimal_mod((decimal*) a, (decimal*) b, res));
return check_result(mask, decimal_mod((decimal_t*) a, (decimal_t*) b, res));
}
@ -320,14 +320,14 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a,
inline
int my_decimal_cmp(const my_decimal *a, const my_decimal *b)
{
return decimal_cmp((decimal*) a, (decimal*) b);
return decimal_cmp((decimal_t*) a, (decimal_t*) b);
}
inline
void max_my_decimal(my_decimal *to, int precision, int frac)
{
DBUG_ASSERT(precision <= DECIMAL_MAX_LENGTH);
max_decimal(precision, frac, (decimal*) to);
max_decimal(precision, frac, (decimal_t*) to);
}
#endif /*my_decimal_h*/

View file

@ -264,6 +264,12 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
/* Flag set if setup_tables already done */
#define OPTION_SETUP_TABLES_DONE (1L << 30)
/*
Maximum length of time zone name that we support
(Time zone name is char(64) in db). mysqlbinlog needs it.
*/
#define MAX_TIME_ZONE_NAME_LENGTH 72
/* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT

View file

@ -3310,9 +3310,10 @@ default_service_handling(char **argv,
int main(int argc, char **argv)
{
/* When several instances are running on the same machine, we
need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
/*
When several instances are running on the same machine, we
need to have an unique named hEventShudown through the
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
*/
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
"MySQLShutdown"), 10);

View file

@ -2095,27 +2095,6 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
}
}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool sys_var_character_set_server::check(THD *thd, set_var *var)
{
/*
To be perfect we should fail even if we are a 5.0.3 slave, a 4.1 master,
and user wants to change our global character set variables. Because
replicating a 4.1 assumes those are not changed. But that's not easy to
do.
*/
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
return sys_var_character_set::check(thd,var);
}
#endif
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
enum_var_type type)
{
@ -2208,20 +2187,6 @@ void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
}
}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool sys_var_collation_server::check(THD *thd, set_var *var)
{
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
return sys_var_collation::check(thd,var);
}
#endif
bool sys_var_collation_server::update(THD *thd, set_var *var)
{
@ -2560,16 +2525,6 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
String str(buff, sizeof(buff), &my_charset_latin1);
String *res= var->value->val_str(&str);
#if defined(HAVE_REPLICATION)
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone");
return 1;
}
#endif
if (!(var->save_result.time_zone=
my_tz_find(res, thd->lex->time_zone_tables_used)))
{
@ -2605,7 +2560,18 @@ byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
if (type == OPT_GLOBAL)
return (byte *)(global_system_variables.time_zone->get_name()->ptr());
else
{
/*
This is an ugly fix for replication: we don't replicate properly queries
invoking system variables' values to update tables; but
CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
replicable (i.e. we tell the binlog code to store the session
timezone). If it's the global value which was used we can't replicate
(binlog code stores session value only).
*/
thd->time_zone_used= 1;
return (byte *)(thd->variables.time_zone->get_name()->ptr());
}
}

View file

@ -565,9 +565,6 @@ class sys_var_character_set_server :public sys_var_character_set
public:
sys_var_character_set_server(const char *name_arg) :
sys_var_character_set(name_arg) {}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool check(THD *thd, set_var *var);
#endif
void set_default(THD *thd, enum_var_type type);
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
};
@ -603,9 +600,6 @@ class sys_var_collation_server :public sys_var_collation
{
public:
sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool check(THD *thd, set_var *var);
#endif
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);

View file

@ -5332,3 +5332,5 @@ ER_STARTUP
eng "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d %s"
ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR
eng "Can't load value from file with fixed size rows to variable"
ER_CANT_CREATE_USER_WITH_GRANT
eng "You are not allowed to create a user with GRANT"

View file

@ -1456,11 +1456,10 @@ be equal for replication to work";
such check will broke everything for them. (And now everything will
work for them because by default both their master and slave will have
'SYSTEM' time zone).
TODO: when the new replication of timezones is sorted out with Dmitri,
change >= '4' to == '4'.
This check is only necessary for 4.x masters (and < 5.0.4 masters but
those were alpha).
*/
if ((*mysql->server_version >= '4') &&
if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
(master_res= mysql_store_result(mysql)))
{
@ -2770,6 +2769,18 @@ void set_slave_thread_options(THD* thd)
thd->variables.completion_type= 0;
}
void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli)
{
thd->variables.character_set_client=
global_system_variables.character_set_client;
thd->variables.collation_connection=
global_system_variables.collation_connection;
thd->variables.collation_server=
global_system_variables.collation_server;
thd->update_charset();
rli->cached_charset_invalidate();
}
/*
init_slave_thread()
*/

View file

@ -562,6 +562,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
const char** errmsg);
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli);
void rotate_relay_log(MASTER_INFO* mi);
extern "C" pthread_handler_decl(handle_slave_io,arg);

View file

@ -1627,7 +1627,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
else if (((thd->variables.sql_mode & MODE_NO_AUTO_CREATE_USER) &&
!password_len) || !create_user)
{
my_error(ER_NO_PERMISSION_TO_CREATE_USER, MYF(0),
my_error(ER_CANT_CREATE_USER_WITH_GRANT, MYF(0),
thd->user, thd->host_or_ip);
goto end;
}

View file

@ -10144,20 +10144,18 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->sum_funcs_end[send_group_parts]);
if (join->having && join->having->val_int() == 0)
error= -1;
else if ((error=table->file->write_row(table->record[0])))
else if ((error= table->file->write_row(table->record[0])))
{
if (create_myisam_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
DBUG_RETURN(-1);
}
if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
if (join->rollup.state != ROLLUP::STATE_NONE)
{
if (join->rollup_write_data((uint) (idx+1), table))
error= 1;
DBUG_RETURN(-1);
}
if (error > 0)
DBUG_RETURN(-1);
if (end_of_records)
DBUG_RETURN(0);
}
@ -12684,17 +12682,21 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
{
/* Check if this is something that is part of this group by */
ORDER *group_tmp;
for (group_tmp= start_group, i-- ;
for (group_tmp= start_group, i= pos ;
group_tmp ; group_tmp= group_tmp->next, i++)
{
if (*group_tmp->item == item)
{
Item_null_result *null_item;
/*
This is an element that is used by the GROUP BY and should be
set to NULL in this level
*/
item->maybe_null= 1; // Value will be null sometimes
Item_null_result *null_item= rollup.null_items[i];
null_item= rollup.null_items[i];
DBUG_ASSERT(null_item->result_field == 0 ||
null_item->result_field ==
((Item_field *) item)->result_field);
null_item->result_field= ((Item_field *) item)->result_field;
item= null_item;
break;

View file

@ -84,6 +84,7 @@ public:
inline char& operator [] (uint32 i) const { return Ptr[i]; }
inline void length(uint32 len) { str_length=len ; }
inline bool is_empty() { return (str_length == 0); }
inline void mark_as_const() { Alloced_length= 0;}
inline const char *ptr() const { return Ptr; }
inline char *c_ptr()
{
@ -205,10 +206,6 @@ public:
}
}
}
inline void shrink_to_length()
{
Alloced_length= str_length;
}
bool is_alloced() { return alloced; }
inline String& operator = (const String &s)
{

View file

@ -613,7 +613,7 @@ int prepare_create_field(create_field *sql_field,
Prepares the table and key structures for table creation.
NOTES
sets create_info->varchar if the table has a varchar or blob.
sets create_info->varchar if the table has a varchar
RETURN VALUES
0 ok
@ -862,12 +862,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
&timestamps, &timestamps_with_niladic,
file->table_flags()))
DBUG_RETURN(-1);
if (sql_field->sql_type == FIELD_TYPE_BLOB ||
sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB ||
sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
sql_field->sql_type == FIELD_TYPE_LONG_BLOB ||
sql_field->sql_type == FIELD_TYPE_GEOMETRY ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR)
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
create_info->varchar= 1;
sql_field->offset= pos;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)

View file

@ -149,6 +149,15 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
*fn_ext(index_file)='\0'; // Remove .frm extension
share->frm_version= head[2];
/*
Check if .frm file created by MySQL 5.0. In this case we want to
display CHAR fields as CHAR and not as VARCHAR.
We do it this way as we want to keep the old frm version to enable
MySQL 4.1 to read these files.
*/
if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
share->frm_version= FRM_VER_TRUE_VARCHAR;
share->db_type= ha_checktype((enum db_type) (uint) *(head+3));
share->db_create_options= db_create_options=uint2korr(head+30);
share->db_options_in_use= share->db_create_options;
@ -1317,6 +1326,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo,
create_info->table_options|=HA_OPTION_LONG_BLOB_PTR; // Use portable blob pointers
int2store(fileinfo+30,create_info->table_options);
fileinfo[32]=0; // No filename anymore
fileinfo[33]=5; // Mark for 5.0 frm file
int4store(fileinfo+34,create_info->avg_row_length);
fileinfo[38]= (create_info->default_table_charset ?
create_info->default_table_charset->number : 0);

View file

@ -2178,7 +2178,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_PRINT("enter", ("time zone name='%s'",
name ? ((String *)name)->c_ptr() : "NULL"));
DBUG_ASSERT(!time_zone_tables_exist || tz_tables);
DBUG_ASSERT(!time_zone_tables_exist || tz_tables || current_thd->slave_thread);
if (!name)
DBUG_RETURN(0);
@ -2210,7 +2210,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
(const byte *)name->ptr(),
name->length())))
result_tz= tmp_tzname->tz;
else if (time_zone_tables_exist)
else if (time_zone_tables_exist && tz_tables)
result_tz= tz_load_from_open_tables(name, tz_tables);
}
@ -2219,6 +2219,58 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_RETURN(result_tz);
}
/*
A more standalone version of my_tz_find(): will open tz tables if needed.
This is so far only used by replication, where time zone setting does not
happen in the usual query context.
SYNOPSIS
my_tz_find_with_opening_tz_tables()
thd - pointer to thread's THD structure
name - time zone specification
DESCRIPTION
This function tries to find a time zone which matches the named passed in
argument. If it fails, it will open time zone tables and re-try the
search.
This function is needed for the slave SQL thread, which does not do the
addition of time zone tables which is usually done during query parsing
(as time zone setting by slave does not happen in mysql_parse() but
before). So it needs to open tz tables by itself if needed.
See notes of my_tz_find() as they also apply here.
RETURN VALUE
Pointer to corresponding Time_zone object. 0 - in case of bad time zone
specification or other error.
*/
Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
{
Time_zone *tz;
DBUG_ENTER("my_tz_find_with_opening_tables");
DBUG_ASSERT(thd);
DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only
if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist)
{
/*
Probably we have not loaded this time zone yet so let us look it up in
our time zone tables. Note that if we don't have tz tables on this
slave, we don't even try.
*/
TABLE_LIST tables[4];
TABLE_LIST *dummy;
TABLE_LIST **dummyp= &dummy;
tz_init_table_list(tables, &dummyp);
if (simple_open_n_lock_tables(thd, tables))
DBUG_RETURN(0);
tz= my_tz_find(name, tables);
/* We need to close tables _now_ to not pollute coming query */
close_thread_tables(thd);
}
DBUG_RETURN(tz);
}
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */

View file

@ -61,6 +61,7 @@ extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr);
extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
extern Time_zone * my_tz_find_with_opening_tz_tables(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free();
@ -96,10 +97,4 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
return FALSE;
}
/*
Maximum length of time zone name that we support
(Time zone name is char(64) in db)
*/
#define MAX_TIME_ZONE_NAME_LENGTH 72
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */

View file

@ -109,20 +109,20 @@
/*
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
So one "decimal_digit" is
So one variable of type decimal_digit_t is limited:
0 < decimal_digit <= DIG_MAX < DIG_BASE
in the struct st_decimal:
in the struct st_decimal_t:
intg is the number of *decimal* digits (NOT number of decimal_digit's !)
intg is the number of *decimal* digits (NOT number of decimal_digit_t's !)
before the point
frac - number of decimal digits after the point
buf is an array of decimal_digit's
len is the length of buf (length of allocated space) in decimal_digit's,
buf is an array of decimal_digit_t's
len is the length of buf (length of allocated space) in decimal_digit_t's,
not in bytes
*/
typedef decimal_digit dec1;
typedef decimal_digit_t dec1;
typedef longlong dec2;
#define DIG_PER_DEC1 9
@ -223,7 +223,7 @@ static const dec1 frac_max[DIG_PER_DEC1-1]={
to->buf and to->len must be set.
*/
void max_decimal(int precision, int frac, decimal *to)
void max_decimal(int precision, int frac, decimal_t *to)
{
int intpart;
dec1 *buf= to->buf;
@ -250,7 +250,7 @@ void max_decimal(int precision, int frac, decimal *to)
}
static dec1 *remove_leading_zeroes(decimal *from, int *intg_result)
static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result)
{
int intg= from->intg, i;
dec1 *buf0= from->buf;
@ -281,7 +281,7 @@ static dec1 *remove_leading_zeroes(decimal *from, int *intg_result)
from number for processing
*/
void decimal_optimize_fraction(decimal *from)
void decimal_optimize_fraction(decimal_t *from)
{
int frac= from->frac, i;
dec1 *buf0= from->buf + ROUND_UP(from->intg) + ROUND_UP(frac) - 1;
@ -328,7 +328,7 @@ void decimal_optimize_fraction(decimal *from)
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
*/
int decimal2string(decimal *from, char *to, int *to_len,
int decimal2string(decimal_t *from, char *to, int *to_len,
int fixed_precision, int fixed_decimals,
char filler)
{
@ -453,7 +453,7 @@ int decimal2string(decimal *from, char *to, int *to_len,
be written by this address
*/
static void digits_bounds(decimal *from, int *start_result, int *end_result)
static void digits_bounds(decimal_t *from, int *start_result, int *end_result)
{
int start, stop, i;
dec1 *buf_beg= from->buf;
@ -520,7 +520,7 @@ static void digits_bounds(decimal *from, int *start_result, int *end_result)
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
*/
void do_mini_left_shift(decimal *dec, int shift, int beg, int last)
void do_mini_left_shift(decimal_t *dec, int shift, int beg, int last)
{
dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1;
dec1 *end= dec->buf + ROUND_UP(last) - 1;
@ -550,7 +550,7 @@ void do_mini_left_shift(decimal *dec, int shift, int beg, int last)
'shift' have to be from 1 to DIG_PER_DEC1-1 (inclusive)
*/
void do_mini_right_shift(decimal *dec, int shift, int beg, int last)
void do_mini_right_shift(decimal_t *dec, int shift, int beg, int last)
{
dec1 *from= dec->buf + ROUND_UP(last) - 1;
dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1;
@ -583,7 +583,7 @@ void do_mini_right_shift(decimal *dec, int shift, int beg, int last)
E_DEC_TRUNCATED number was rounded to fit into buffer
*/
int decimal_shift(decimal *dec, int shift)
int decimal_shift(decimal_t *dec, int shift)
{
/* index of first non zero digit (all indexes from 0) */
int beg;
@ -780,7 +780,8 @@ int decimal_shift(decimal *dec, int shift)
(to make error handling easier)
*/
int internal_str2dec(const char *from, decimal *to, char **end, my_bool fixed)
int
internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
{
const char *s= from, *s1, *endp, *end_of_string= *end;
int i, intg, frac, error, intg1, frac1;
@ -937,7 +938,7 @@ fatal_error:
E_DEC_OK
*/
int decimal2double(decimal *from, double *to)
int decimal2double(decimal_t *from, double *to)
{
double x=0, t=DIG_BASE;
int intg, frac;
@ -963,7 +964,7 @@ int decimal2double(decimal *from, double *to)
E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED
*/
int double2decimal(double from, decimal *to)
int double2decimal(double from, decimal_t *to)
{
/* TODO: fix it, when we'll have dtoa */
char s[400], *end;
@ -972,7 +973,7 @@ int double2decimal(double from, decimal *to)
return string2decimal(s, to, &end);
}
static int ull2dec(ulonglong from, decimal *to)
static int ull2dec(ulonglong from, decimal_t *to)
{
int intg1, error=E_DEC_OK;
ulonglong x=from;
@ -998,20 +999,20 @@ static int ull2dec(ulonglong from, decimal *to)
return error;
}
int ulonglong2decimal(ulonglong from, decimal *to)
int ulonglong2decimal(ulonglong from, decimal_t *to)
{
to->sign=0;
return ull2dec(from, to);
}
int longlong2decimal(longlong from, decimal *to)
int longlong2decimal(longlong from, decimal_t *to)
{
if ((to->sign= from < 0))
return ull2dec(-from, to);
return ull2dec(from, to);
}
int decimal2ulonglong(decimal *from, ulonglong *to)
int decimal2ulonglong(decimal_t *from, ulonglong *to)
{
dec1 *buf=from->buf;
ulonglong x=0;
@ -1040,7 +1041,7 @@ int decimal2ulonglong(decimal *from, ulonglong *to)
return E_DEC_OK;
}
int decimal2longlong(decimal *from, longlong *to)
int decimal2longlong(decimal_t *from, longlong *to)
{
dec1 *buf=from->buf;
longlong x=0;
@ -1112,7 +1113,7 @@ int decimal2longlong(decimal *from, longlong *to)
3. The first intg % DIG_PER_DEC1 digits are stored in the reduced
number of bytes (enough bytes to store this number of digits -
see dig2bytes)
4. same for frac - full decimal_digit's are stored as is,
4. same for frac - full decimal_digit_t's are stored as is,
the last frac % DIG_PER_DEC1 digits - in the reduced number of bytes.
5. If the number is negative - every byte is inversed.
5. The very first bit of the resulting byte array is inverted (because
@ -1122,7 +1123,7 @@ int decimal2longlong(decimal *from, longlong *to)
1234567890.1234
internally is represented as 3 decimal_digit's
internally is represented as 3 decimal_digit_t's
1 234567890 123400000
@ -1131,13 +1132,13 @@ int decimal2longlong(decimal *from, longlong *to)
00-00-00-01 0D-FB-38-D2 07-5A-EF-40
now, middle decimal_digit is full - it stores 9 decimal digits. It goes
now, middle decimal_digit_t is full - it stores 9 decimal digits. It goes
into binary representation as is:
........... 0D-FB-38-D2 ............
First decimal_digit has only one decimal digit. We can store one digit in
First decimal_digit_t has only one decimal digit. We can store one digit in
one byte, no need to waste four:
01 0D-FB-38-D2 ............
@ -1155,7 +1156,7 @@ int decimal2longlong(decimal *from, longlong *to)
7E F2 04 37 2D FB 2D
*/
int decimal2bin(decimal *from, char *to, int precision, int frac)
int decimal2bin(decimal_t *from, char *to, int precision, int frac)
{
dec1 mask=from->sign ? -1 : 0, *buf1=from->buf, *stop1;
int error=E_DEC_OK, intg=precision-frac,
@ -1283,7 +1284,7 @@ int decimal2bin(decimal *from, char *to, int precision, int frac)
E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW
*/
int bin2decimal(char *from, decimal *to, int precision, int scale)
int bin2decimal(char *from, decimal_t *to, int precision, int scale)
{
int error=E_DEC_OK, intg=precision-scale,
intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
@ -1424,7 +1425,9 @@ int decimal_bin_size(int precision, int scale)
E_DEC_OK/E_DEC_TRUNCATED
*/
int decimal_round(decimal *from, decimal *to, int scale, decimal_round_mode mode)
int
decimal_round(decimal_t *from, decimal_t *to, int scale,
decimal_round_mode mode)
{
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
frac1=ROUND_UP(from->frac), round_digit,
@ -1585,7 +1588,7 @@ done:
multiply by sizeof(dec1)
*/
int decimal_result_size(decimal *from1, decimal *from2, char op, int param)
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
{
switch (op) {
case '-':
@ -1604,7 +1607,7 @@ int decimal_result_size(decimal *from1, decimal *from2, char op, int param)
return -1; /* shut up the warning */
}
static int do_add(decimal *from1, decimal *from2, decimal *to)
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
@ -1680,7 +1683,7 @@ static int do_add(decimal *from1, decimal *from2, decimal *to)
/* to=from1-from2.
if to==0, return -1/0/+1 - the result of the comparison */
static int do_sub(decimal *from1, decimal *from2, decimal *to)
static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
@ -1741,7 +1744,7 @@ static int do_sub(decimal *from1, decimal *from2, decimal *to)
/* ensure that always from1 > from2 (and intg1 >= intg2) */
if (carry)
{
swap_variables(decimal *,from1,from1);
swap_variables(decimal_t *,from1,from1);
swap_variables(dec1 *,start1, start2);
swap_variables(int,intg1,intg2);
swap_variables(int,frac1,frac2);
@ -1807,28 +1810,28 @@ static int do_sub(decimal *from1, decimal *from2, decimal *to)
return error;
}
int decimal_add(decimal *from1, decimal *from2, decimal *to)
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
if (likely(from1->sign == from2->sign))
return do_add(from1, from2, to);
return do_sub(from1, from2, to);
}
int decimal_sub(decimal *from1, decimal *from2, decimal *to)
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
if (likely(from1->sign == from2->sign))
return do_sub(from1, from2, to);
return do_add(from1, from2, to);
}
int decimal_cmp(decimal *from1, decimal *from2)
int decimal_cmp(decimal_t *from1, decimal_t *from2)
{
if (likely(from1->sign == from2->sign))
return do_sub(from1, from2, 0);
return from1->sign > from2->sign ? -1 : 1;
}
int decimal_is_zero(decimal *from)
int decimal_is_zero(decimal_t *from)
{
dec1 *buf1=from->buf,
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
@ -1859,7 +1862,7 @@ int decimal_is_zero(decimal *from)
XXX if this library is to be used with huge numbers of thousands of
digits, fast multiplication must be implemented.
*/
int decimal_mul(decimal *from1, decimal *from2, decimal *to)
int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
@ -1932,8 +1935,8 @@ int decimal_mul(decimal *from1, decimal *from2, decimal *to)
changed to malloc (or at least fallback to malloc if alloca() fails)
but then, decimal_mod() should be rewritten too :(
*/
static int do_div_mod(decimal *from1, decimal *from2,
decimal *to, decimal *mod, int scale_incr)
static int do_div_mod(decimal_t *from1, decimal_t *from2,
decimal_t *to, decimal_t *mod, int scale_incr)
{
int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1,
frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2,
@ -2208,7 +2211,8 @@ done:
see do_div_mod()
*/
int decimal_div(decimal *from1, decimal *from2, decimal *to, int scale_incr)
int
decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr)
{
return do_div_mod(from1, from2, to, 0, scale_incr);
}
@ -2240,7 +2244,7 @@ int decimal_div(decimal *from1, decimal *from2, decimal *to, int scale_incr)
thus, there's no requirement for M or N to be integers
*/
int decimal_mod(decimal *from1, decimal *from2, decimal *to)
int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to)
{
return do_div_mod(from1, from2, 0, to, 0);
}
@ -2248,10 +2252,10 @@ int decimal_mod(decimal *from1, decimal *from2, decimal *to)
#ifdef MAIN
int full= 0;
decimal a, b, c;
decimal_t a, b, c;
char buf1[100], buf2[100], buf3[100];
void dump_decimal(decimal *d)
void dump_decimal(decimal_t *d)
{
int i;
printf("/* intg=%d, frac=%d, sign=%d, buf[]={", d->intg, d->frac, d->sign);
@ -2271,7 +2275,7 @@ void check_result_code(int actual, int want)
}
void print_decimal(decimal *d, const char *orig, int actual, int want)
void print_decimal(decimal_t *d, const char *orig, int actual, int want)
{
char s[100];
int slen=sizeof(s);