Merge chilla.local:/home/mydev/mysql-5.1--main
into chilla.local:/home/mydev/mysql-5.1-amerge
This commit is contained in:
commit
4cdb1469e0
@ -22,6 +22,7 @@ extern const char *not_error_sqlstate;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern CHARSET_INFO *default_client_charset_info;
|
||||||
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
|
||||||
my_bool default_value, uint server_capabilities);
|
my_bool default_value, uint server_capabilities);
|
||||||
void free_rows(MYSQL_DATA *cur);
|
void free_rows(MYSQL_DATA *cur);
|
||||||
|
@ -37,6 +37,8 @@ extern "C"
|
|||||||
int check_user(THD *thd, enum enum_server_command command,
|
int check_user(THD *thd, enum enum_server_command command,
|
||||||
const char *passwd, uint passwd_len, const char *db,
|
const char *passwd, uint passwd_len, const char *db,
|
||||||
bool check_count);
|
bool check_count);
|
||||||
|
void thd_init_client_charset(THD *thd, uint cs_number);
|
||||||
|
|
||||||
C_MODE_START
|
C_MODE_START
|
||||||
|
|
||||||
#include <mysql.h>
|
#include <mysql.h>
|
||||||
@ -604,11 +606,14 @@ err:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
int check_embedded_connection(MYSQL *mysql)
|
int check_embedded_connection(MYSQL *mysql)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
THD *thd= (THD*)mysql->thd;
|
THD *thd= (THD*)mysql->thd;
|
||||||
|
thd_init_client_charset(thd, mysql->charset->number);
|
||||||
|
thd->update_charset();
|
||||||
Security_context *sctx= thd->security_ctx;
|
Security_context *sctx= thd->security_ctx;
|
||||||
sctx->host_or_ip= sctx->host= (char*) my_localhost;
|
sctx->host_or_ip= sctx->host= (char*) my_localhost;
|
||||||
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
|
strmake(sctx->priv_host, (char*) my_localhost, MAX_HOSTNAME-1);
|
||||||
@ -627,6 +632,8 @@ int check_embedded_connection(MYSQL *mysql)
|
|||||||
char scramble_buff[SCRAMBLE_LENGTH];
|
char scramble_buff[SCRAMBLE_LENGTH];
|
||||||
int passwd_len;
|
int passwd_len;
|
||||||
|
|
||||||
|
thd_init_client_charset(thd, mysql->charset->number);
|
||||||
|
thd->update_charset();
|
||||||
if (mysql->options.client_ip)
|
if (mysql->options.client_ip)
|
||||||
{
|
{
|
||||||
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
|
sctx->host= my_strdup(mysql->options.client_ip, MYF(0));
|
||||||
|
@ -90,49 +90,7 @@ static void end_server(MYSQL *mysql)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mysql_init_charset(MYSQL *mysql)
|
int mysql_init_character_set(MYSQL *mysql);
|
||||||
{
|
|
||||||
char charset_name_buff[16], *charset_name;
|
|
||||||
|
|
||||||
if ((charset_name=mysql->options.charset_name))
|
|
||||||
{
|
|
||||||
const char *save=charsets_dir;
|
|
||||||
if (mysql->options.charset_dir)
|
|
||||||
charsets_dir=mysql->options.charset_dir;
|
|
||||||
mysql->charset=get_charset_by_name(mysql->options.charset_name,
|
|
||||||
MYF(MY_WME));
|
|
||||||
charsets_dir=save;
|
|
||||||
}
|
|
||||||
else if (mysql->server_language)
|
|
||||||
{
|
|
||||||
charset_name=charset_name_buff;
|
|
||||||
sprintf(charset_name,"%d",mysql->server_language); /* In case of errors */
|
|
||||||
mysql->charset=get_charset((uint8) mysql->server_language, MYF(MY_WME));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mysql->charset=default_charset_info;
|
|
||||||
|
|
||||||
if (!mysql->charset)
|
|
||||||
{
|
|
||||||
mysql->net.last_errno=CR_CANT_READ_CHARSET;
|
|
||||||
strmov(mysql->net.sqlstate, "HY0000");
|
|
||||||
if (mysql->options.charset_dir)
|
|
||||||
sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
|
|
||||||
charset_name ? charset_name : "unknown",
|
|
||||||
mysql->options.charset_dir);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char cs_dir_name[FN_REFLEN];
|
|
||||||
get_charsets_dir(cs_dir_name);
|
|
||||||
sprintf(mysql->net.last_error,ER(mysql->net.last_errno),
|
|
||||||
charset_name ? charset_name : "unknown",
|
|
||||||
cs_dir_name);
|
|
||||||
}
|
|
||||||
return mysql->net.last_errno;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MYSQL * STDCALL
|
MYSQL * STDCALL
|
||||||
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||||
@ -222,10 +180,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||||||
|
|
||||||
init_embedded_mysql(mysql, client_flag, db_name);
|
init_embedded_mysql(mysql, client_flag, db_name);
|
||||||
|
|
||||||
if (check_embedded_connection(mysql))
|
if (mysql_init_character_set(mysql))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (mysql_init_charset(mysql))
|
if (check_embedded_connection(mysql))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
mysql->server_status= SERVER_STATUS_AUTOCOMMIT;
|
mysql->server_status= SERVER_STATUS_AUTOCOMMIT;
|
||||||
|
@ -13812,6 +13812,8 @@ select * from t1 where i between 2 and 4 and v in ('def','3r4f','lmn');
|
|||||||
i v
|
i v
|
||||||
4 3r4f
|
4 3r4f
|
||||||
alter table t1 data directory="$MYSQLTEST_VARDIR/tmp";
|
alter table t1 data directory="$MYSQLTEST_VARDIR/tmp";
|
||||||
|
Warnings:
|
||||||
|
Warning 0 DATA DIRECTORY option ignored
|
||||||
select * from t1;
|
select * from t1;
|
||||||
i v
|
i v
|
||||||
1 def
|
1 def
|
||||||
|
@ -81,6 +81,12 @@ makedate(1997,1)
|
|||||||
select makedate(1997,0);
|
select makedate(1997,0);
|
||||||
makedate(1997,0)
|
makedate(1997,0)
|
||||||
NULL
|
NULL
|
||||||
|
select makedate(9999,365);
|
||||||
|
makedate(9999,365)
|
||||||
|
9999-12-31
|
||||||
|
select makedate(9999,366);
|
||||||
|
makedate(9999,366)
|
||||||
|
NULL
|
||||||
select addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
|
select addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002");
|
||||||
addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002")
|
addtime("1997-12-31 23:59:59.999999", "1 1:1:1.000002")
|
||||||
1998-01-02 01:01:01.000001
|
1998-01-02 01:01:01.000001
|
||||||
|
@ -361,6 +361,12 @@ extract(SECOND FROM "1999-01-02 10:11:12")
|
|||||||
select extract(MONTH FROM "2001-02-00");
|
select extract(MONTH FROM "2001-02-00");
|
||||||
extract(MONTH FROM "2001-02-00")
|
extract(MONTH FROM "2001-02-00")
|
||||||
2
|
2
|
||||||
|
SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
|
||||||
|
DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE)
|
||||||
|
9999-12-31 00:00:00
|
||||||
|
SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
|
||||||
|
DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE)
|
||||||
|
9999-12-31 00:00:00
|
||||||
SELECT EXTRACT(QUARTER FROM '2004-01-15') AS quarter;
|
SELECT EXTRACT(QUARTER FROM '2004-01-15') AS quarter;
|
||||||
quarter
|
quarter
|
||||||
1
|
1
|
||||||
|
@ -816,3 +816,43 @@ check table t1 extended;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 geometry NOT NULL default '',
|
||||||
|
SPATIAL KEY i1 (c1(32))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
CHECK TABLE t1 EXTENDED;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 geometry NOT NULL default '',
|
||||||
|
SPATIAL KEY i1 (c1(32))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-65.7402776999 -96.6686111000,
|
||||||
|
-65.7372222000 -96.5516666000,
|
||||||
|
-65.8502777000 -96.5461111000,
|
||||||
|
-65.8527777000 -96.6627777000,
|
||||||
|
-65.7402776999 -96.6686111000))'));
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
CHECK TABLE t1 EXTENDED;
|
||||||
|
Table Op Msg_type Msg_text
|
||||||
|
test.t1 check status OK
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -694,3 +694,13 @@ alter table t1 add primary key pti(pt);
|
|||||||
ERROR 42000: BLOB/TEXT column 'pt' used in key specification without a key length
|
ERROR 42000: BLOB/TEXT column 'pt' used in key specification without a key length
|
||||||
alter table t1 add primary key pti(pt(20));
|
alter table t1 add primary key pti(pt(20));
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (g GEOMETRY);
|
||||||
|
select * from t1;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def test t1 t1 g g 255 4294967295 0 Y 144 0 63
|
||||||
|
g
|
||||||
|
select asbinary(g) from t1;
|
||||||
|
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||||
|
def asbinary(g) 252 8192 0 Y 128 0 63
|
||||||
|
asbinary(g)
|
||||||
|
drop table t1;
|
||||||
|
@ -74,18 +74,24 @@ t9 CREATE TABLE `t9` (
|
|||||||
) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/'
|
) ENGINE=MyISAM AUTO_INCREMENT=16725 DEFAULT CHARSET=latin1 DATA DIRECTORY='MYSQLTEST_VARDIR/tmp/' INDEX DIRECTORY='MYSQLTEST_VARDIR/run/'
|
||||||
drop database mysqltest;
|
drop database mysqltest;
|
||||||
create table t1 (a int not null) engine=myisam;
|
create table t1 (a int not null) engine=myisam;
|
||||||
|
Warnings:
|
||||||
|
Warning 0 DATA DIRECTORY option ignored
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) NOT NULL
|
`a` int(11) NOT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
alter table t1 add b int;
|
alter table t1 add b int;
|
||||||
|
Warnings:
|
||||||
|
Warning 0 DATA DIRECTORY option ignored
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`a` int(11) NOT NULL,
|
`a` int(11) NOT NULL,
|
||||||
`b` int(11) DEFAULT NULL
|
`b` int(11) DEFAULT NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
|
Warnings:
|
||||||
|
Warning 0 INDEX DIRECTORY option ignored
|
||||||
show create table t1;
|
show create table t1;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
|
@ -43,6 +43,8 @@ select weekofyear("1997-11-30 23:59:59.000001");
|
|||||||
|
|
||||||
select makedate(1997,1);
|
select makedate(1997,1);
|
||||||
select makedate(1997,0);
|
select makedate(1997,0);
|
||||||
|
select makedate(9999,365);
|
||||||
|
select makedate(9999,366);
|
||||||
|
|
||||||
#Time functions
|
#Time functions
|
||||||
|
|
||||||
|
@ -143,6 +143,10 @@ select extract(SECOND FROM "1999-01-02 10:11:12");
|
|||||||
select extract(MONTH FROM "2001-02-00");
|
select extract(MONTH FROM "2001-02-00");
|
||||||
|
|
||||||
#
|
#
|
||||||
|
# MySQL Bugs: #12356: DATE_SUB or DATE_ADD incorrectly returns null
|
||||||
|
#
|
||||||
|
SELECT DATE_SUB(str_to_date('9999-12-31 00:01:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
|
||||||
|
SELECT DATE_ADD(str_to_date('9999-12-30 23:59:00','%Y-%m-%d %H:%i:%s'), INTERVAL 1 MINUTE);
|
||||||
# test EXTRACT QUARTER (Bug #18100)
|
# test EXTRACT QUARTER (Bug #18100)
|
||||||
#
|
#
|
||||||
|
|
||||||
|
@ -187,4 +187,48 @@ check table t1 extended;
|
|||||||
|
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#17877 - Corrupted spatial index
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 geometry NOT NULL default '',
|
||||||
|
SPATIAL KEY i1 (c1(32))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
# This showed a missing key.
|
||||||
|
CHECK TABLE t1 EXTENDED;
|
||||||
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
c1 geometry NOT NULL default '',
|
||||||
|
SPATIAL KEY i1 (c1(32))
|
||||||
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-65.7402776999 -96.6686111000,
|
||||||
|
-65.7372222000 -96.5516666000,
|
||||||
|
-65.8502777000 -96.5461111000,
|
||||||
|
-65.8527777000 -96.6627777000,
|
||||||
|
-65.7402776999 -96.6686111000))'));
|
||||||
|
# This is the same as the first insert to get a non-unique key.
|
||||||
|
INSERT INTO t1 (c1) VALUES (
|
||||||
|
PolygonFromText('POLYGON((-18.6086111000 -66.9327777000,
|
||||||
|
-18.6055555000 -66.8158332999,
|
||||||
|
-18.7186111000 -66.8102777000,
|
||||||
|
-18.7211111000 -66.9269443999,
|
||||||
|
-18.6086111000 -66.9327777000))'));
|
||||||
|
# This showed (and still shows) OK.
|
||||||
|
CHECK TABLE t1 EXTENDED;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
# End of 4.1 tests
|
||||||
|
@ -409,3 +409,10 @@ create table t1(pt GEOMETRY);
|
|||||||
alter table t1 add primary key pti(pt);
|
alter table t1 add primary key pti(pt);
|
||||||
alter table t1 add primary key pti(pt(20));
|
alter table t1 add primary key pti(pt(20));
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--enable_metadata
|
||||||
|
create table t1 (g GEOMETRY);
|
||||||
|
select * from t1;
|
||||||
|
select asbinary(g) from t1;
|
||||||
|
--disable_metadata
|
||||||
|
drop table t1;
|
||||||
|
@ -125,6 +125,8 @@ static void mysql_close_free(MYSQL *mysql);
|
|||||||
static int wait_for_data(my_socket fd, uint timeout);
|
static int wait_for_data(my_socket fd, uint timeout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CHARSET_INFO *default_client_charset_info = &my_charset_latin1;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
A modified version of connect(). my_connect() allows you to specify
|
A modified version of connect(). my_connect() allows you to specify
|
||||||
@ -1426,7 +1428,7 @@ mysql_init(MYSQL *mysql)
|
|||||||
bzero((char*) (mysql), sizeof(*(mysql)));
|
bzero((char*) (mysql), sizeof(*(mysql)));
|
||||||
mysql->options.connect_timeout= CONNECT_TIMEOUT;
|
mysql->options.connect_timeout= CONNECT_TIMEOUT;
|
||||||
mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
|
mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
|
||||||
mysql->charset=default_charset_info;
|
mysql->charset=default_client_charset_info;
|
||||||
strmov(mysql->net.sqlstate, not_error_sqlstate);
|
strmov(mysql->net.sqlstate, not_error_sqlstate);
|
||||||
/*
|
/*
|
||||||
By default, we are a replication pivot. The caller must reset it
|
By default, we are a replication pivot. The caller must reset it
|
||||||
@ -1655,6 +1657,50 @@ static MYSQL_METHODS client_methods=
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
C_MODE_START
|
||||||
|
int mysql_init_character_set(MYSQL *mysql)
|
||||||
|
{
|
||||||
|
NET *net= &mysql->net;
|
||||||
|
/* Set character set */
|
||||||
|
if (!mysql->options.charset_name &&
|
||||||
|
!(mysql->options.charset_name=
|
||||||
|
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *save= charsets_dir;
|
||||||
|
if (mysql->options.charset_dir)
|
||||||
|
charsets_dir=mysql->options.charset_dir;
|
||||||
|
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
|
||||||
|
MY_CS_PRIMARY, MYF(MY_WME));
|
||||||
|
charsets_dir= save;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mysql->charset)
|
||||||
|
{
|
||||||
|
net->last_errno=CR_CANT_READ_CHARSET;
|
||||||
|
strmov(net->sqlstate, unknown_sqlstate);
|
||||||
|
if (mysql->options.charset_dir)
|
||||||
|
my_snprintf(net->last_error, sizeof(net->last_error)-1,
|
||||||
|
ER(net->last_errno),
|
||||||
|
mysql->options.charset_name,
|
||||||
|
mysql->options.charset_dir);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char cs_dir_name[FN_REFLEN];
|
||||||
|
get_charsets_dir(cs_dir_name);
|
||||||
|
my_snprintf(net->last_error, sizeof(net->last_error)-1,
|
||||||
|
ER(net->last_errno),
|
||||||
|
mysql->options.charset_name,
|
||||||
|
cs_dir_name);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
C_MODE_END
|
||||||
|
|
||||||
|
|
||||||
MYSQL *
|
MYSQL *
|
||||||
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||||
const char *passwd, const char *db,
|
const char *passwd, const char *db,
|
||||||
@ -1992,42 +2038,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set character set */
|
if (mysql_init_character_set(mysql))
|
||||||
if (!mysql->options.charset_name &&
|
|
||||||
!(mysql->options.charset_name=
|
|
||||||
my_strdup(MYSQL_DEFAULT_CHARSET_NAME,MYF(MY_WME))))
|
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
{
|
|
||||||
const char *save= charsets_dir;
|
|
||||||
if (mysql->options.charset_dir)
|
|
||||||
charsets_dir=mysql->options.charset_dir;
|
|
||||||
mysql->charset=get_charset_by_csname(mysql->options.charset_name,
|
|
||||||
MY_CS_PRIMARY, MYF(MY_WME));
|
|
||||||
charsets_dir= save;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mysql->charset)
|
|
||||||
{
|
|
||||||
net->last_errno=CR_CANT_READ_CHARSET;
|
|
||||||
strmov(net->sqlstate, unknown_sqlstate);
|
|
||||||
if (mysql->options.charset_dir)
|
|
||||||
my_snprintf(net->last_error, sizeof(net->last_error)-1,
|
|
||||||
ER(net->last_errno),
|
|
||||||
mysql->options.charset_name,
|
|
||||||
mysql->options.charset_dir);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char cs_dir_name[FN_REFLEN];
|
|
||||||
get_charsets_dir(cs_dir_name);
|
|
||||||
my_snprintf(net->last_error, sizeof(net->last_error)-1,
|
|
||||||
ER(net->last_errno),
|
|
||||||
mysql->options.charset_name,
|
|
||||||
cs_dir_name);
|
|
||||||
}
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Save connection information */
|
/* Save connection information */
|
||||||
if (!my_multi_malloc(MYF(0),
|
if (!my_multi_malloc(MYF(0),
|
||||||
|
28
sql/field.cc
28
sql/field.cc
@ -1536,7 +1536,8 @@ bool Field::optimize_range(uint idx, uint part)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table)
|
Field *Field::new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
|
bool keep_type __attribute__((unused)))
|
||||||
{
|
{
|
||||||
Field *tmp;
|
Field *tmp;
|
||||||
if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
|
if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
|
||||||
@ -1561,7 +1562,7 @@ Field *Field::new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
|||||||
uint new_null_bit)
|
uint new_null_bit)
|
||||||
{
|
{
|
||||||
Field *tmp;
|
Field *tmp;
|
||||||
if ((tmp= new_field(root, new_table)))
|
if ((tmp= new_field(root, new_table, table == new_table)))
|
||||||
{
|
{
|
||||||
tmp->ptr= new_ptr;
|
tmp->ptr= new_ptr;
|
||||||
tmp->null_ptr= new_null_ptr;
|
tmp->null_ptr= new_null_ptr;
|
||||||
@ -6371,11 +6372,12 @@ uint Field_string::max_packed_col_length(uint max_length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
|
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
|
bool keep_type)
|
||||||
{
|
{
|
||||||
Field *field;
|
Field *field;
|
||||||
if (type() != MYSQL_TYPE_VAR_STRING || table == new_table)
|
if (type() != MYSQL_TYPE_VAR_STRING || keep_type)
|
||||||
return Field::new_field(root, new_table);
|
return Field::new_field(root, new_table, keep_type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Old VARCHAR field which should be modified to a VARCHAR on copy
|
Old VARCHAR field which should be modified to a VARCHAR on copy
|
||||||
@ -6384,17 +6386,7 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
|
|||||||
*/
|
*/
|
||||||
if ((field= new Field_varstring(field_length, maybe_null(), field_name,
|
if ((field= new Field_varstring(field_length, maybe_null(), field_name,
|
||||||
new_table->s, charset())))
|
new_table->s, charset())))
|
||||||
{
|
|
||||||
field->init(new_table);
|
field->init(new_table);
|
||||||
/*
|
|
||||||
delayed_insert::get_local_table() needs a ptr copied from old table.
|
|
||||||
This is what other new_field() methods do too. The above method of
|
|
||||||
Field_varstring sets ptr to NULL.
|
|
||||||
*/
|
|
||||||
field->ptr= ptr;
|
|
||||||
field->null_ptr= null_ptr;
|
|
||||||
field->null_bit= null_bit;
|
|
||||||
}
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6896,9 +6888,11 @@ int Field_varstring::cmp_binary(const char *a_ptr, const char *b_ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table)
|
Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
|
bool keep_type)
|
||||||
{
|
{
|
||||||
Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table);
|
Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
|
||||||
|
keep_type);
|
||||||
if (res)
|
if (res)
|
||||||
res->length_bytes= length_bytes;
|
res->length_bytes= length_bytes;
|
||||||
return res;
|
return res;
|
||||||
|
@ -219,7 +219,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool can_be_compared_as_longlong() const { return FALSE; }
|
virtual bool can_be_compared_as_longlong() const { return FALSE; }
|
||||||
virtual void free() {}
|
virtual void free() {}
|
||||||
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
|
bool keep_type);
|
||||||
virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
char *new_ptr, uchar *new_null_ptr,
|
char *new_ptr, uchar *new_null_ptr,
|
||||||
uint new_null_bit);
|
uint new_null_bit);
|
||||||
@ -1044,7 +1045,7 @@ public:
|
|||||||
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
enum_field_types real_type() const { return FIELD_TYPE_STRING; }
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1117,7 +1118,7 @@ public:
|
|||||||
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
|
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||||
bool has_charset(void) const
|
bool has_charset(void) const
|
||||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type);
|
||||||
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||||
char *new_ptr, uchar *new_null_ptr,
|
char *new_ptr, uchar *new_null_ptr,
|
||||||
uint new_null_bit);
|
uint new_null_bit);
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
|
Item_geometry_func(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
|
||||||
Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
|
Item_geometry_func(List<Item> &list) :Item_str_func(list) {}
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec();
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_geometry_from_text: public Item_geometry_func
|
class Item_func_geometry_from_text: public Item_geometry_func
|
||||||
@ -67,6 +68,7 @@ public:
|
|||||||
Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
|
Item_func_as_wkb(Item *a): Item_geometry_func(a) {}
|
||||||
const char *func_name() const { return "aswkb"; }
|
const char *func_name() const { return "aswkb"; }
|
||||||
String *val_str(String *);
|
String *val_str(String *);
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_func_geometry_type: public Item_str_func
|
class Item_func_geometry_type: public Item_str_func
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
/* TODO: Move month and days to language files */
|
/* TODO: Move month and days to language files */
|
||||||
|
|
||||||
|
/* Day number for Dec 31st, 9999 */
|
||||||
#define MAX_DAY_NUMBER 3652424L
|
#define MAX_DAY_NUMBER 3652424L
|
||||||
|
|
||||||
static const char *month_names[]=
|
static const char *month_names[]=
|
||||||
@ -408,7 +409,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
if (yearday > 0)
|
if (yearday > 0)
|
||||||
{
|
{
|
||||||
uint days= calc_daynr(l_time->year,1,1) + yearday - 1;
|
uint days= calc_daynr(l_time->year,1,1) + yearday - 1;
|
||||||
if (days <= 0 || days >= MAX_DAY_NUMBER)
|
if (days <= 0 || days > MAX_DAY_NUMBER)
|
||||||
goto err;
|
goto err;
|
||||||
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
|
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
|
||||||
}
|
}
|
||||||
@ -454,7 +455,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
|
|||||||
(weekday - 1);
|
(weekday - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (days <= 0 || days >= MAX_DAY_NUMBER)
|
if (days <= 0 || days > MAX_DAY_NUMBER)
|
||||||
goto err;
|
goto err;
|
||||||
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
|
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
|
||||||
}
|
}
|
||||||
@ -1962,7 +1963,6 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
|
|||||||
|
|
||||||
if (date_sub_interval)
|
if (date_sub_interval)
|
||||||
interval.neg = !interval.neg;
|
interval.neg = !interval.neg;
|
||||||
|
|
||||||
if (ltime->year < YY_MAGIC_BELOW)
|
if (ltime->year < YY_MAGIC_BELOW)
|
||||||
return (null_value=1);
|
return (null_value=1);
|
||||||
|
|
||||||
@ -2450,7 +2450,7 @@ String *Item_func_makedate::val_str(String *str)
|
|||||||
|
|
||||||
days= calc_daynr(yearnr,1,1) + daynr - 1;
|
days= calc_daynr(yearnr,1,1) + daynr - 1;
|
||||||
/* Day number from year 0 to 9999-12-31 */
|
/* Day number from year 0 to 9999-12-31 */
|
||||||
if (days >= 0 && days < MAX_DAY_NUMBER)
|
if (days >= 0 && days <= MAX_DAY_NUMBER)
|
||||||
{
|
{
|
||||||
null_value=0;
|
null_value=0;
|
||||||
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
|
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
|
||||||
|
@ -1015,7 +1015,7 @@ bool select_send::send_data(List<Item> &items)
|
|||||||
Protocol *protocol= thd->protocol;
|
Protocol *protocol= thd->protocol;
|
||||||
char buff[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH];
|
||||||
String buffer(buff, sizeof(buff), &my_charset_bin);
|
String buffer(buff, sizeof(buff), &my_charset_bin);
|
||||||
DBUG_ENTER("send_data");
|
DBUG_ENTER("select_send::send_data");
|
||||||
|
|
||||||
protocol->prepare_for_resend();
|
protocol->prepare_for_resend();
|
||||||
Item *item;
|
Item *item;
|
||||||
@ -1228,7 +1228,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
|
|||||||
bool select_export::send_data(List<Item> &items)
|
bool select_export::send_data(List<Item> &items)
|
||||||
{
|
{
|
||||||
|
|
||||||
DBUG_ENTER("send_data");
|
DBUG_ENTER("select_export::send_data");
|
||||||
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
|
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
|
||||||
bool space_inited=0;
|
bool space_inited=0;
|
||||||
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
||||||
@ -1385,7 +1385,7 @@ bool select_dump::send_data(List<Item> &items)
|
|||||||
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
|
||||||
tmp.length(0);
|
tmp.length(0);
|
||||||
Item *item;
|
Item *item;
|
||||||
DBUG_ENTER("send_data");
|
DBUG_ENTER("select_dump::send_data");
|
||||||
|
|
||||||
if (unit->offset_limit_cnt)
|
if (unit->offset_limit_cnt)
|
||||||
{ // using limit offset,count
|
{ // using limit offset,count
|
||||||
|
@ -17,6 +17,44 @@
|
|||||||
|
|
||||||
/* Insert of records */
|
/* Insert of records */
|
||||||
|
|
||||||
|
/*
|
||||||
|
INSERT DELAYED
|
||||||
|
|
||||||
|
Insert delayed is distinguished from a normal insert by lock_type ==
|
||||||
|
TL_WRITE_DELAYED instead of TL_WRITE. It first tries to open a
|
||||||
|
"delayed" table (delayed_get_table()), but falls back to
|
||||||
|
open_and_lock_tables() on error and proceeds as normal insert then.
|
||||||
|
|
||||||
|
Opening a "delayed" table means to find a delayed insert thread that
|
||||||
|
has the table open already. If this fails, a new thread is created and
|
||||||
|
waited for to open and lock the table.
|
||||||
|
|
||||||
|
If accessing the thread succeeded, in
|
||||||
|
delayed_insert::get_local_table() the table of the thread is copied
|
||||||
|
for local use. A copy is required because the normal insert logic
|
||||||
|
works on a target table, but the other threads table object must not
|
||||||
|
be used. The insert logic uses the record buffer to create a record.
|
||||||
|
And the delayed insert thread uses the record buffer to pass the
|
||||||
|
record to the table handler. So there must be different objects. Also
|
||||||
|
the copied table is not included in the lock, so that the statement
|
||||||
|
can proceed even if the real table cannot be accessed at this moment.
|
||||||
|
|
||||||
|
Copying a table object is not a trivial operation. Besides the TABLE
|
||||||
|
object there are the field pointer array, the field objects and the
|
||||||
|
record buffer. After copying the field objects, their pointers into
|
||||||
|
the record must be "moved" to point to the new record buffer.
|
||||||
|
|
||||||
|
After this setup the normal insert logic is used. Only that for
|
||||||
|
delayed inserts write_delayed() is called instead of write_record().
|
||||||
|
It inserts the rows into a queue and signals the delayed insert thread
|
||||||
|
instead of writing directly to the table.
|
||||||
|
|
||||||
|
The delayed insert thread awakes from the signal. It locks the table,
|
||||||
|
inserts the rows from the queue, unlocks the table, and waits for the
|
||||||
|
next signal. It does normally live until a FLUSH TABLES or SHUTDOWN.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
#include "sp_head.h"
|
#include "sp_head.h"
|
||||||
#include "sql_trigger.h"
|
#include "sql_trigger.h"
|
||||||
@ -1515,6 +1553,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
|||||||
TABLE *copy;
|
TABLE *copy;
|
||||||
TABLE_SHARE *share= table->s;
|
TABLE_SHARE *share= table->s;
|
||||||
byte *bitmap;
|
byte *bitmap;
|
||||||
|
DBUG_ENTER("delayed_insert::get_local_table");
|
||||||
|
|
||||||
/* First request insert thread to get a lock */
|
/* First request insert thread to get a lock */
|
||||||
status=1;
|
status=1;
|
||||||
@ -1538,6 +1577,13 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Allocate memory for the TABLE object, the field pointers array, and
|
||||||
|
one record buffer of reclength size. Normally a table has three
|
||||||
|
record buffers of rec_buff_length size, which includes alignment
|
||||||
|
bytes. Since the table copy is used for creating one record only,
|
||||||
|
the other record buffers and alignment are unnecessary.
|
||||||
|
*/
|
||||||
client_thd->proc_info="allocating local table";
|
client_thd->proc_info="allocating local table";
|
||||||
copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
|
copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
|
||||||
(share->fields+1)*sizeof(Field**)+
|
(share->fields+1)*sizeof(Field**)+
|
||||||
@ -1545,23 +1591,28 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
|||||||
share->column_bitmap_size*2);
|
share->column_bitmap_size*2);
|
||||||
if (!copy)
|
if (!copy)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
/* Copy the TABLE object. */
|
||||||
*copy= *table;
|
*copy= *table;
|
||||||
|
|
||||||
/* We don't need to change the file handler here */
|
/* We don't need to change the file handler here */
|
||||||
field= copy->field= (Field**) (copy+1);
|
/* Assign the pointers for the field pointers array and the record. */
|
||||||
bitmap= (byte*) (field+share->fields+1);
|
field= copy->field= (Field**) (copy + 1);
|
||||||
copy->record[0]= (bitmap+ share->column_bitmap_size*2);
|
bitmap= (byte*) (field + share->fields + 1);
|
||||||
memcpy((char*) copy->record[0],(char*) table->record[0],share->reclength);
|
copy->record[0]= (bitmap + share->column_bitmap_size * 2);
|
||||||
|
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
|
||||||
/* Make a copy of all fields */
|
/*
|
||||||
|
Make a copy of all fields.
|
||||||
adjust_ptrs=PTR_BYTE_DIFF(copy->record[0],table->record[0]);
|
The copied fields need to point into the copied record. This is done
|
||||||
|
by copying the field objects with their old pointer values and then
|
||||||
found_next_number_field=table->found_next_number_field;
|
"move" the pointers by the distance between the original and copied
|
||||||
for (org_field=table->field ; *org_field ; org_field++,field++)
|
records. That way we preserve the relative positions in the records.
|
||||||
|
*/
|
||||||
|
adjust_ptrs= PTR_BYTE_DIFF(copy->record[0], table->record[0]);
|
||||||
|
found_next_number_field= table->found_next_number_field;
|
||||||
|
for (org_field= table->field; *org_field; org_field++, field++)
|
||||||
{
|
{
|
||||||
if (!(*field= (*org_field)->new_field(client_thd->mem_root,copy)))
|
if (!(*field= (*org_field)->new_field(client_thd->mem_root, copy, 1)))
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
(*field)->orig_table= copy; // Remove connection
|
(*field)->orig_table= copy; // Remove connection
|
||||||
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
|
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
|
||||||
if (*org_field == found_next_number_field)
|
if (*org_field == found_next_number_field)
|
||||||
@ -1594,14 +1645,14 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
|
|||||||
copy->read_set= ©->def_read_set;
|
copy->read_set= ©->def_read_set;
|
||||||
copy->write_set= ©->def_write_set;
|
copy->write_set= ©->def_write_set;
|
||||||
|
|
||||||
return copy;
|
DBUG_RETURN(copy);
|
||||||
|
|
||||||
/* Got fatal error */
|
/* Got fatal error */
|
||||||
error:
|
error:
|
||||||
tables_in_use--;
|
tables_in_use--;
|
||||||
status=1;
|
status=1;
|
||||||
pthread_cond_signal(&cond); // Inform thread about abort
|
pthread_cond_signal(&cond); // Inform thread about abort
|
||||||
return 0;
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -818,6 +818,37 @@ static void reset_mqh(LEX_USER *lu, bool get_them= 0)
|
|||||||
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void thd_init_client_charset(THD *thd, uint cs_number)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Use server character set and collation if
|
||||||
|
- opt_character_set_client_handshake is not set
|
||||||
|
- client has not specified a character set
|
||||||
|
- client character set is the same as the servers
|
||||||
|
- client character set doesn't exists in server
|
||||||
|
*/
|
||||||
|
if (!opt_character_set_client_handshake ||
|
||||||
|
!(thd->variables.character_set_client= get_charset(cs_number, MYF(0))) ||
|
||||||
|
!my_strcasecmp(&my_charset_latin1,
|
||||||
|
global_system_variables.character_set_client->name,
|
||||||
|
thd->variables.character_set_client->name))
|
||||||
|
{
|
||||||
|
thd->variables.character_set_client=
|
||||||
|
global_system_variables.character_set_client;
|
||||||
|
thd->variables.collation_connection=
|
||||||
|
global_system_variables.collation_connection;
|
||||||
|
thd->variables.character_set_results=
|
||||||
|
global_system_variables.character_set_results;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thd->variables.character_set_results=
|
||||||
|
thd->variables.collation_connection=
|
||||||
|
thd->variables.character_set_client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Perform handshake, authorize client and update thd ACL variables.
|
Perform handshake, authorize client and update thd ACL variables.
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@ -953,33 +984,7 @@ static int check_connection(THD *thd)
|
|||||||
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
|
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
|
||||||
thd->max_client_packet_length= uint4korr(net->read_pos+4);
|
thd->max_client_packet_length= uint4korr(net->read_pos+4);
|
||||||
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
|
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
|
||||||
/*
|
thd_init_client_charset(thd, (uint) net->read_pos[8]);
|
||||||
Use server character set and collation if
|
|
||||||
- opt_character_set_client_handshake is not set
|
|
||||||
- client has not specified a character set
|
|
||||||
- client character set is the same as the servers
|
|
||||||
- client character set doesn't exists in server
|
|
||||||
*/
|
|
||||||
if (!opt_character_set_client_handshake ||
|
|
||||||
!(thd->variables.character_set_client=
|
|
||||||
get_charset((uint) net->read_pos[8], MYF(0))) ||
|
|
||||||
!my_strcasecmp(&my_charset_latin1,
|
|
||||||
global_system_variables.character_set_client->name,
|
|
||||||
thd->variables.character_set_client->name))
|
|
||||||
{
|
|
||||||
thd->variables.character_set_client=
|
|
||||||
global_system_variables.character_set_client;
|
|
||||||
thd->variables.collation_connection=
|
|
||||||
global_system_variables.collation_connection;
|
|
||||||
thd->variables.character_set_results=
|
|
||||||
global_system_variables.character_set_results;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
thd->variables.character_set_results=
|
|
||||||
thd->variables.collation_connection=
|
|
||||||
thd->variables.character_set_client;
|
|
||||||
}
|
|
||||||
thd->update_charset();
|
thd->update_charset();
|
||||||
end= (char*) net->read_pos+32;
|
end= (char*) net->read_pos+32;
|
||||||
}
|
}
|
||||||
@ -3112,6 +3117,12 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Don't yet allow changing of symlinks with ALTER TABLE */
|
/* Don't yet allow changing of symlinks with ALTER TABLE */
|
||||||
|
if (lex->create_info.data_file_name)
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
||||||
|
"DATA DIRECTORY option ignored");
|
||||||
|
if (lex->create_info.index_file_name)
|
||||||
|
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
|
||||||
|
"INDEX DIRECTORY option ignored");
|
||||||
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
lex->create_info.data_file_name=lex->create_info.index_file_name=0;
|
||||||
/* ALTER TABLE ends previous transaction */
|
/* ALTER TABLE ends previous transaction */
|
||||||
if (end_active_trans(thd))
|
if (end_active_trans(thd))
|
||||||
|
@ -8058,7 +8058,8 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
|
|||||||
org_field->field_name, table->s,
|
org_field->field_name, table->s,
|
||||||
org_field->charset());
|
org_field->charset());
|
||||||
else
|
else
|
||||||
new_field= org_field->new_field(thd->mem_root, table);
|
new_field= org_field->new_field(thd->mem_root, table,
|
||||||
|
table == org_field->table);
|
||||||
if (new_field)
|
if (new_field)
|
||||||
{
|
{
|
||||||
new_field->init(table);
|
new_field->init(table);
|
||||||
@ -13166,7 +13167,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
saved value
|
saved value
|
||||||
*/
|
*/
|
||||||
Field *field= item->field;
|
Field *field= item->field;
|
||||||
item->result_field=field->new_field(thd->mem_root,field->table);
|
item->result_field=field->new_field(thd->mem_root,field->table, 1);
|
||||||
char *tmp=(char*) sql_alloc(field->pack_length()+1);
|
char *tmp=(char*) sql_alloc(field->pack_length()+1);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -733,7 +733,8 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table)
|
|||||||
QQ: it is supposed that it is ok to use this function for field
|
QQ: it is supposed that it is ok to use this function for field
|
||||||
cloning...
|
cloning...
|
||||||
*/
|
*/
|
||||||
if (!(*old_fld= (*fld)->new_field(&table->mem_root, table)))
|
if (!(*old_fld= (*fld)->new_field(&table->mem_root, table,
|
||||||
|
table == (*fld)->table)))
|
||||||
return 1;
|
return 1;
|
||||||
(*old_fld)->move_field_offset((my_ptrdiff_t)(table->record[1] -
|
(*old_fld)->move_field_offset((my_ptrdiff_t)(table->record[1] -
|
||||||
table->record[0]));
|
table->record[0]));
|
||||||
|
@ -1456,7 +1456,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
Create a new field for the key part that matches the index
|
Create a new field for the key part that matches the index
|
||||||
*/
|
*/
|
||||||
field= key_part->field=field->new_field(&outparam->mem_root,
|
field= key_part->field=field->new_field(&outparam->mem_root,
|
||||||
outparam);
|
outparam, 0);
|
||||||
field->field_length= key_part->length;
|
field->field_length= key_part->length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -749,6 +749,7 @@ void make_truncated_value_warning(THD *thd, const char *str_val,
|
|||||||
ER_TRUNCATED_WRONG_VALUE, warn_buff);
|
ER_TRUNCATED_WRONG_VALUE, warn_buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Daynumber from year 0 to 9999-12-31 */
|
||||||
#define MAX_DAY_NUMBER 3652424L
|
#define MAX_DAY_NUMBER 3652424L
|
||||||
|
|
||||||
bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval)
|
bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval)
|
||||||
@ -804,7 +805,7 @@ bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval)
|
|||||||
ltime->hour= (uint) (sec/3600);
|
ltime->hour= (uint) (sec/3600);
|
||||||
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
|
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
|
||||||
/* Day number from year 0 to 9999-12-31 */
|
/* Day number from year 0 to 9999-12-31 */
|
||||||
if ((ulonglong) daynr >= MAX_DAY_NUMBER)
|
if ((ulonglong) daynr > MAX_DAY_NUMBER)
|
||||||
goto invalid_date;
|
goto invalid_date;
|
||||||
get_date_from_daynr((long) daynr, <ime->year, <ime->month,
|
get_date_from_daynr((long) daynr, <ime->year, <ime->month,
|
||||||
<ime->day);
|
<ime->day);
|
||||||
@ -815,7 +816,7 @@ bool date_add_interval(TIME *ltime, interval_type int_type, INTERVAL interval)
|
|||||||
period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
|
period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
|
||||||
sign * (long) interval.day);
|
sign * (long) interval.day);
|
||||||
/* Daynumber from year 0 to 9999-12-31 */
|
/* Daynumber from year 0 to 9999-12-31 */
|
||||||
if ((ulong) period >= MAX_DAY_NUMBER)
|
if ((ulong) period > MAX_DAY_NUMBER)
|
||||||
goto invalid_date;
|
goto invalid_date;
|
||||||
get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day);
|
get_date_from_daynr((long) period,<ime->year,<ime->month,<ime->day);
|
||||||
break;
|
break;
|
||||||
|
@ -1158,13 +1158,14 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
|
|||||||
#ifdef HAVE_RTREE_KEYS
|
#ifdef HAVE_RTREE_KEYS
|
||||||
(keyinfo->flag & HA_SPATIAL) ?
|
(keyinfo->flag & HA_SPATIAL) ?
|
||||||
rtree_find_first(info, key, info->lastkey, key_length,
|
rtree_find_first(info, key, info->lastkey, key_length,
|
||||||
SEARCH_SAME) :
|
MBR_EQUAL | MBR_DATA) :
|
||||||
#endif
|
#endif
|
||||||
_mi_search(info,keyinfo,info->lastkey,key_length,
|
_mi_search(info,keyinfo,info->lastkey,key_length,
|
||||||
SEARCH_SAME, info->s->state.key_root[key]);
|
SEARCH_SAME, info->s->state.key_root[key]);
|
||||||
if (search_result)
|
if (search_result)
|
||||||
{
|
{
|
||||||
mi_check_print_error(param,"Record at: %10s Can't find key for index: %2d",
|
mi_check_print_error(param,"Record at: %10s "
|
||||||
|
"Can't find key for index: %2d",
|
||||||
llstr(start_recpos,llbuff),key+1);
|
llstr(start_recpos,llbuff),key+1);
|
||||||
if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
|
if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
|
||||||
goto err2;
|
goto err2;
|
||||||
|
@ -60,6 +60,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
|
my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
|
||||||
MI_CREATE_INFO tmp_create_info;
|
MI_CREATE_INFO tmp_create_info;
|
||||||
DBUG_ENTER("mi_create");
|
DBUG_ENTER("mi_create");
|
||||||
|
DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
|
||||||
|
keys, columns, uniques, flags));
|
||||||
|
|
||||||
if (!ci)
|
if (!ci)
|
||||||
{
|
{
|
||||||
@ -482,6 +484,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
uniques * MI_UNIQUEDEF_SIZE +
|
uniques * MI_UNIQUEDEF_SIZE +
|
||||||
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
|
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
|
||||||
columns*MI_COLUMNDEF_SIZE);
|
columns*MI_COLUMNDEF_SIZE);
|
||||||
|
DBUG_PRINT("info", ("info_length: %u", info_length));
|
||||||
|
/* There are only 16 bits for the total header length. */
|
||||||
|
if (info_length > 65535)
|
||||||
|
{
|
||||||
|
my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
|
||||||
|
"indexes and/or unique constraints.",
|
||||||
|
MYF(0), name + dirname_length(name));
|
||||||
|
my_errno= HA_WRONG_CREATE_OPTION;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
bmove(share.state.header.file_version,(byte*) myisam_file_magic,4);
|
bmove(share.state.header.file_version,(byte*) myisam_file_magic,4);
|
||||||
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
|
||||||
@ -650,6 +662,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
errpos=3;
|
errpos=3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBUG_PRINT("info", ("write state info and base info"));
|
||||||
if (mi_state_info_write(file, &share.state, 2) ||
|
if (mi_state_info_write(file, &share.state, 2) ||
|
||||||
mi_base_info_write(file, &share.base))
|
mi_base_info_write(file, &share.base))
|
||||||
goto err;
|
goto err;
|
||||||
@ -663,6 +676,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Write key and keyseg definitions */
|
/* Write key and keyseg definitions */
|
||||||
|
DBUG_PRINT("info", ("write key and keyseg definitions"));
|
||||||
for (i=0 ; i < share.base.keys - uniques; i++)
|
for (i=0 ; i < share.base.keys - uniques; i++)
|
||||||
{
|
{
|
||||||
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
|
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
|
||||||
@ -713,6 +727,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Save unique definition */
|
/* Save unique definition */
|
||||||
|
DBUG_PRINT("info", ("write unique definitions"));
|
||||||
for (i=0 ; i < share.state.header.uniques ; i++)
|
for (i=0 ; i < share.state.header.uniques ; i++)
|
||||||
{
|
{
|
||||||
HA_KEYSEG *keyseg_end;
|
HA_KEYSEG *keyseg_end;
|
||||||
@ -743,6 +758,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
DBUG_PRINT("info", ("write field definitions"));
|
||||||
for (i=0 ; i < share.base.fields ; i++)
|
for (i=0 ; i < share.base.fields ; i++)
|
||||||
if (mi_recinfo_write(file, &recinfo[i]))
|
if (mi_recinfo_write(file, &recinfo[i]))
|
||||||
goto err;
|
goto err;
|
||||||
@ -757,6 +773,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enlarge files */
|
/* Enlarge files */
|
||||||
|
DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
|
||||||
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
|
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -34,12 +34,24 @@ int mi_delete_table(const char *name)
|
|||||||
#ifdef USE_RAID
|
#ifdef USE_RAID
|
||||||
{
|
{
|
||||||
MI_INFO *info;
|
MI_INFO *info;
|
||||||
/* we use 'open_for_repair' to be able to delete a crashed table */
|
/*
|
||||||
if (!(info=mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
|
When built with RAID support, we need to determine if this table
|
||||||
DBUG_RETURN(my_errno);
|
makes use of the raid feature. If yes, we need to remove all raid
|
||||||
raid_type = info->s->base.raid_type;
|
chunks. This is done with my_raid_delete(). Unfortunately it is
|
||||||
raid_chunks = info->s->base.raid_chunks;
|
necessary to open the table just to check this. We use
|
||||||
mi_close(info);
|
'open_for_repair' to be able to open even a crashed table. If even
|
||||||
|
this open fails, we assume no raid configuration for this table
|
||||||
|
and try to remove the normal data file only. This may however
|
||||||
|
leave the raid chunks behind.
|
||||||
|
*/
|
||||||
|
if (!(info= mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
|
||||||
|
raid_type= 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
raid_type= info->s->base.raid_type;
|
||||||
|
raid_chunks= info->s->base.raid_chunks;
|
||||||
|
mi_close(info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef EXTRA_DEBUG
|
#ifdef EXTRA_DEBUG
|
||||||
check_table_is_closed(name,"delete");
|
check_table_is_closed(name,"delete");
|
||||||
|
@ -1329,6 +1329,9 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
|
|||||||
info->rec_cache.pos_in_file <= block_info.next_filepos &&
|
info->rec_cache.pos_in_file <= block_info.next_filepos &&
|
||||||
flush_io_cache(&info->rec_cache))
|
flush_io_cache(&info->rec_cache))
|
||||||
goto err;
|
goto err;
|
||||||
|
/* A corrupted table can have wrong pointers. (Bug# 19835) */
|
||||||
|
if (block_info.next_filepos == HA_OFFSET_ERROR)
|
||||||
|
goto panic;
|
||||||
info->rec_cache.seek_not_done=1;
|
info->rec_cache.seek_not_done=1;
|
||||||
if ((b_type=_mi_get_block_info(&block_info,file,
|
if ((b_type=_mi_get_block_info(&block_info,file,
|
||||||
block_info.next_filepos))
|
block_info.next_filepos))
|
||||||
|
@ -68,6 +68,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
|||||||
|
|
||||||
if (fast_mi_readinfo(info))
|
if (fast_mi_readinfo(info))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (share->concurrent_insert)
|
if (share->concurrent_insert)
|
||||||
rw_rdlock(&share->key_root_lock[inx]);
|
rw_rdlock(&share->key_root_lock[inx]);
|
||||||
|
|
||||||
@ -90,24 +91,35 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
|
|||||||
case HA_KEY_ALG_BTREE:
|
case HA_KEY_ALG_BTREE:
|
||||||
default:
|
default:
|
||||||
if (!_mi_search(info, keyinfo, key_buff, use_key_length,
|
if (!_mi_search(info, keyinfo, key_buff, use_key_length,
|
||||||
myisam_read_vec[search_flag], info->s->state.key_root[inx]))
|
myisam_read_vec[search_flag], info->s->state.key_root[inx]))
|
||||||
{
|
{
|
||||||
while (info->lastpos >= info->state->data_file_length)
|
/*
|
||||||
|
If we are searching for an exact key (including the data pointer)
|
||||||
|
and this was added by an concurrent insert,
|
||||||
|
then the result is "key not found".
|
||||||
|
*/
|
||||||
|
if ((search_flag == HA_READ_KEY_EXACT) &&
|
||||||
|
(info->lastpos >= info->state->data_file_length))
|
||||||
|
{
|
||||||
|
my_errno= HA_ERR_KEY_NOT_FOUND;
|
||||||
|
info->lastpos= HA_OFFSET_ERROR;
|
||||||
|
}
|
||||||
|
else while (info->lastpos >= info->state->data_file_length)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Skip rows that are inserted by other threads since we got a lock
|
Skip rows that are inserted by other threads since we got a lock
|
||||||
Note that this can only happen if we are not searching after an
|
Note that this can only happen if we are not searching after an
|
||||||
exact key, because the keys are sorted according to position
|
exact key, because the keys are sorted according to position
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (_mi_search_next(info, keyinfo, info->lastkey,
|
if (_mi_search_next(info, keyinfo, info->lastkey,
|
||||||
info->lastkey_length,
|
info->lastkey_length,
|
||||||
myisam_readnext_vec[search_flag],
|
myisam_readnext_vec[search_flag],
|
||||||
info->s->state.key_root[inx]))
|
info->s->state.key_root[inx]))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (share->concurrent_insert)
|
if (share->concurrent_insert)
|
||||||
rw_unlock(&share->key_root_lock[inx]);
|
rw_unlock(&share->key_root_lock[inx]);
|
||||||
|
|
||||||
|
@ -183,9 +183,11 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save searched key */
|
/*
|
||||||
memcpy(info->first_mbr_key, key, keyinfo->keylength -
|
Save searched key, include data pointer.
|
||||||
info->s->base.rec_reflength);
|
The data pointer is required if the search_flag contains MBR_DATA.
|
||||||
|
*/
|
||||||
|
memcpy(info->first_mbr_key, key, keyinfo->keylength);
|
||||||
info->last_rkey_length = key_length;
|
info->last_rkey_length = key_length;
|
||||||
|
|
||||||
info->rtree_recursion_depth = -1;
|
info->rtree_recursion_depth = -1;
|
||||||
|
@ -52,10 +52,14 @@
|
|||||||
if (EQUAL_CMP(amin, amax, bmin, bmax)) \
|
if (EQUAL_CMP(amin, amax, bmin, bmax)) \
|
||||||
return 1; \
|
return 1; \
|
||||||
} \
|
} \
|
||||||
else /* if (nextflag & MBR_DISJOINT) */ \
|
else if (nextflag & MBR_DISJOINT) \
|
||||||
{ \
|
{ \
|
||||||
if (DISJOINT_CMP(amin, amax, bmin, bmax)) \
|
if (DISJOINT_CMP(amin, amax, bmin, bmax)) \
|
||||||
return 1; \
|
return 1; \
|
||||||
|
}\
|
||||||
|
else /* if unknown comparison operator */ \
|
||||||
|
{ \
|
||||||
|
DBUG_ASSERT(0); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
|
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user