Commit bda3e099 authored by monty@donna.mysql.fi's avatar monty@donna.mysql.fi

Merged some functions and removed some unused client functions.

Remember UNION for ALTER TABLE
Added test for if we are supporting transactions.
Don't allow REPLACE to replace a row when we have generated an auto_increment key
Fixed bug when using BLOB keys
Fixed bug in SET @variable=user.
parent 7b275cf2
This diff is collapsed.
...@@ -1412,13 +1412,13 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) ...@@ -1412,13 +1412,13 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
else else
ds= &ds_res; ds= &ds_res;
if((flags & QUERY_SEND) && if ((flags & QUERY_SEND) &&
(q_error = mysql_send_query(mysql, q->query))) (q_error = mysql_send_query(mysql, q->query, strlen(q->query))))
die("At line %u: unable to send query '%s'", start_lineno, q->query); die("At line %u: unable to send query '%s'", start_lineno, q->query);
if(!(flags & QUERY_REAP)) if(!(flags & QUERY_REAP))
return 0; return 0;
if (mysql_reap_query(mysql)) if (mysql_read_query_result(mysql))
{ {
if (q->require_file) if (q->require_file)
abort_not_supported_test(); abort_not_supported_test();
......
...@@ -229,12 +229,11 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, ...@@ -229,12 +229,11 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
void STDCALL mysql_close(MYSQL *sock); void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db); int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q); int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q); int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
int STDCALL mysql_reap_query(MYSQL *mysql); unsigned int length);
int STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q, int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
unsigned int length); unsigned int length);
int STDCALL mysql_real_send_query(MYSQL *mysql, const char *q,
unsigned int len);
int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); int STDCALL mysql_create_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_shutdown(MYSQL *mysql); int STDCALL mysql_shutdown(MYSQL *mysql);
......
...@@ -1700,87 +1700,30 @@ mysql_query(MYSQL *mysql, const char *query) ...@@ -1700,87 +1700,30 @@ mysql_query(MYSQL *mysql, const char *query)
return mysql_real_query(mysql,query, (uint) strlen(query)); return mysql_real_query(mysql,query, (uint) strlen(query));
} }
int STDCALL /*
mysql_send_query(MYSQL* mysql, const char* query) Send the query and return so we can do something else.
{ Needs to be followed by mysql_read_query_result() when we want to
return mysql_real_send_query(mysql, query, strlen(query)); finish processing it.
}
/* send the query and return so we can do something else */
/* needs to be followed by mysql_reap_query() when we want to
finish processing it
*/ */
int STDCALL
mysql_real_send_query(MYSQL* mysql, const char* query, uint len)
{
return simple_command(mysql, COM_QUERY, query, len, 1);
}
int STDCALL int STDCALL
mysql_reap_query(MYSQL* mysql) mysql_send_query(MYSQL* mysql, const char* query, uint length)
{ {
uchar *pos; return simple_command(mysql, COM_QUERY, query, length, 1);
ulong field_count;
MYSQL_DATA *fields;
uint len;
DBUG_ENTER("mysql_reap_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
if((len = net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1);
free_old_query(mysql); /* Free old result */
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0)
{
mysql->affected_rows= net_field_length_ll(&pos);
mysql->insert_id= net_field_length_ll(&pos);
if (mysql->server_capabilities & CLIENT_TRANSACTIONS)
{
mysql->server_status=uint2korr(pos); pos+=2;
}
if (pos < mysql->net.read_pos+len && net_field_length(&pos))
mysql->info=(char*) pos;
DBUG_RETURN(0);
}
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{
int error=send_file_to_server(mysql,(char*) pos);
if ((len=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(-1);
goto get_info; /* Get info packet */
}
if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
mysql->server_status|= SERVER_STATUS_IN_TRANS;
mysql->extra_info= net_field_length_ll(&pos); /* Maybe number of rec */
if (!(fields=read_rows(mysql,(MYSQL_FIELD*) 0,5)))
DBUG_RETURN(-1);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
(uint) field_count,0,
(my_bool) test(mysql->server_capabilities &
CLIENT_LONG_FLAG))))
DBUG_RETURN(-1);
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
DBUG_RETURN(0);
} }
int STDCALL int STDCALL mysql_read_query_result(MYSQL *mysql)
mysql_real_query(MYSQL *mysql, const char *query, uint length)
{ {
uchar *pos; uchar *pos;
ulong field_count; ulong field_count;
MYSQL_DATA *fields; MYSQL_DATA *fields;
DBUG_ENTER("mysql_real_query"); uint length;
DBUG_PRINT("enter",("handle: %lx",mysql)); DBUG_ENTER("mysql_read_query_result");
DBUG_PRINT("query",("Query = \"%s\"",query));
if (simple_command(mysql,COM_QUERY,query,length,1) || if ((length = net_safe_read(mysql)) == packet_error)
(length=net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1); DBUG_RETURN(-1);
free_old_query(mysql); /* Free old result */ free_old_query(mysql); /* Free old result */
get_info: get_info:
pos=(uchar*) mysql->net.read_pos; pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0) if ((field_count= net_field_length(&pos)) == 0)
{ {
...@@ -1817,6 +1760,16 @@ mysql_real_query(MYSQL *mysql, const char *query, uint length) ...@@ -1817,6 +1760,16 @@ mysql_real_query(MYSQL *mysql, const char *query, uint length)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length)
{
DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query));
if (simple_command(mysql,COM_QUERY,query,length,1))
DBUG_RETURN(-1);
DBUG_RETURN(mysql_read_query_result(mysql));
}
static int static int
send_file_to_server(MYSQL *mysql, const char *filename) send_file_to_server(MYSQL *mysql, const char *filename)
......
...@@ -483,3 +483,10 @@ i j ...@@ -483,3 +483,10 @@ i j
1 2 1 2
build_path build_path
current current
a b
a 2
a b
a 2
a b
a 1
a 2
...@@ -120,14 +120,14 @@ UserId ...@@ -120,14 +120,14 @@ UserId
b b
1 1
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t3 index a a 4 NULL 6 Using index; Using temporary t3 index a a 5 NULL 6 Using index; Using temporary
t2 index a a 4 NULL 5 Using index; Distinct t2 index a a 4 NULL 5 Using index; Distinct
t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 where used; Distinct t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 where used; Distinct
a a
1 1
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary
t3 ref a a 5 t1.a 12 Using index; Distinct t3 ref a a 5 t1.a 10 Using index; Distinct
a a
1 1
2 2
......
...@@ -10,3 +10,10 @@ name_id name ...@@ -10,3 +10,10 @@ name_id name
name_id name name_id name
name_id name name_id name
2 [T,U]_axpby 2 [T,U]_axpby
a b
a 2
a b
a 2
a b
a 1
a 2
...@@ -103,9 +103,6 @@ test2 ...@@ -103,9 +103,6 @@ test2
test2 test2
c c
c c
test1
test1
test1
incr othr incr othr
incr othr incr othr
1 10 1 10
...@@ -118,4 +115,15 @@ count(*) ...@@ -118,4 +115,15 @@ count(*)
20 20
count(*) count(*)
20 20
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0',
PRIMARY KEY (`incr`)
) TYPE=MRG_MyISAM UNION=(t1,t2)
Table Create Table
t3 CREATE TABLE `t3` (
`incr` int(11) NOT NULL default '0',
`othr` int(11) NOT NULL default '0'
) TYPE=MRG_MyISAM UNION=(t1,t2)
a a
...@@ -728,3 +728,18 @@ where ...@@ -728,3 +728,18 @@ where
t3.platform_id = 2; t3.platform_id = 2;
drop table t1, t2, t3, t4, t5, t6,t7; drop table t1, t2, t3, t4, t5, t6,t7;
#
# Test with blob + tinyint key
#
CREATE TABLE t1 (
a tinytext NOT NULL,
b tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (a(32),b)
) TYPE=BDB;
INSERT INTO t1 VALUES ('a',1),('a',2);
SELECT * FROM t1 WHERE a='a' AND b=2;
SELECT * FROM t1 WHERE a='a' AND b in (2);
SELECT * FROM t1 WHERE a='a' AND b in (1,2);
drop table t1;
...@@ -144,3 +144,19 @@ INSERT INTO t1 VALUES (1, 1, 1, 1, 'a'); ...@@ -144,3 +144,19 @@ INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
INSERT INTO t1 VALUES (1, 1, 1, 1, 'b'); INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
!$1062 INSERT INTO t1 VALUES (1, 1, 1, 1, 'a'); !$1062 INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
drop table t1; drop table t1;
#
# Test with blob + tinyint key
# (Failed for Greg Valure)
#
CREATE TABLE t1 (
a tinytext NOT NULL,
b tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (a(32),b)
) TYPE=MyISAM;
INSERT INTO t1 VALUES ('a',1),('a',2);
SELECT * FROM t1 WHERE a='a' AND b=2;
SELECT * FROM t1 WHERE a='a' AND b in (2);
SELECT * FROM t1 WHERE a='a' AND b in (1,2);
drop table t1;
...@@ -50,7 +50,7 @@ insert into t2 (c) values ('test2'); ...@@ -50,7 +50,7 @@ insert into t2 (c) values ('test2');
insert into t2 (c) values ('test2'); insert into t2 (c) values ('test2');
select * from t3; select * from t3;
select * from t3; select * from t3;
delete from t3; delete from t3 where 1=1;
select * from t3; select * from t3;
select * from t1; select * from t1;
drop table t3,t2,t1; drop table t3,t2,t1;
...@@ -78,6 +78,16 @@ alter table t3 UNION=(t1,t2); ...@@ -78,6 +78,16 @@ alter table t3 UNION=(t1,t2);
select count(*) from t3; select count(*) from t3;
alter table t3 TYPE=MYISAM; alter table t3 TYPE=MYISAM;
select count(*) from t3; select count(*) from t3;
# Test that ALTER TABLE rembers the old UNION
drop table t3;
CREATE TABLE t3 (incr int not null, othr int not null, primary key(incr))
TYPE=MERGE UNION=(t1,t2);
show create table t3;
alter table t3 drop primary key;
show create table t3;
drop table t3,t2,t1; drop table t3,t2,t1;
# #
......
...@@ -20,3 +20,17 @@ replace into t1 (gesuchnr,benutzer_id) values (1,1); ...@@ -20,3 +20,17 @@ replace into t1 (gesuchnr,benutzer_id) values (1,1);
alter table t1 type=heap; alter table t1 type=heap;
replace into t1 (gesuchnr,benutzer_id) values (1,1); replace into t1 (gesuchnr,benutzer_id) values (1,1);
drop table t1; drop table t1;
#
# Test when using replace on a key that has used up it's whole range
#
create table t1 (a tinyint not null auto_increment primary key, b char(20));
insert into t1 values (126,"first"),(0,"last");
--error 1062
insert into t1 values (0,"error");
--error 1062
replace into t1 values (0,"error");
replace into t1 values (126,"first updated");
select * from t1;
drop table t1;
...@@ -31,12 +31,6 @@ ...@@ -31,12 +31,6 @@
#define INCL_BASE #define INCL_BASE
#define INCL_NOPMAPI #define INCL_NOPMAPI
#include <os2emx.h> #include <os2emx.h>
#endif
#ifndef __EMX__
#ifdef HAVE_FCNTL
static struct flock lock; /* Must be static for sun-sparc */
#endif
#endif #endif
/* Lock a part of a file */ /* Lock a part of a file */
...@@ -124,29 +118,32 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, ...@@ -124,29 +118,32 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
} }
#else #else
#if defined(HAVE_FCNTL) #if defined(HAVE_FCNTL)
lock.l_type= (short) locktype;
lock.l_whence=0L;
lock.l_start=(long) start;
lock.l_len=(long) length;
if (MyFlags & MY_DONT_WAIT)
{ {
if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */ struct flock lock;
DBUG_RETURN(0); /* Ok, file locked */ lock.l_type= (short) locktype;
DBUG_PRINT("info",("Was locked, trying with alarm")); lock.l_whence=0L;
ALARM_INIT; lock.l_start=(long) start;
while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST && lock.l_len=(long) length;
errno == EINTR) if (MyFlags & MY_DONT_WAIT)
{ /* Setup again so we don`t miss it */ {
ALARM_REINIT; if (fcntl(fd,F_SETLK,&lock) != -1) /* Check if we can lock */
DBUG_RETURN(0); /* Ok, file locked */
DBUG_PRINT("info",("Was locked, trying with alarm"));
ALARM_INIT;
while ((value=fcntl(fd,F_SETLKW,&lock)) && ! ALARM_TEST &&
errno == EINTR)
{ /* Setup again so we don`t miss it */
ALARM_REINIT;
}
ALARM_END;
if (value != -1)
DBUG_RETURN(0);
if (errno == EINTR)
errno=EAGAIN;
} }
ALARM_END; else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
if (value != -1)
DBUG_RETURN(0); DBUG_RETURN(0);
if (errno == EINTR)
errno=EAGAIN;
} }
else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
DBUG_RETURN(0);
#else #else
if (MyFlags & MY_SEEK_NOT_DONE) if (MyFlags & MY_SEEK_NOT_DONE)
VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))); VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)));
......
...@@ -482,9 +482,12 @@ check_or_range("id3","select_range_key2"); ...@@ -482,9 +482,12 @@ check_or_range("id3","select_range_key2");
# Check reading on direct key on id and id3 # Check reading on direct key on id and id3
check_select_key("id","select_key_prefix"); check_select_key("*","id","select_key_prefix");
check_select_key2("id","id2","select_key"); check_select_key2("*","id","id2","select_key");
check_select_key("id3","select_key2"); check_select_key2("id,id2","id","id2","select_key_return_key");
check_select_key("*","id3","select_key2");
check_select_key("id3","id3","select_key2_return_key");
check_select_key("id1,id2","id3","select_key2_return_prim");
#### ####
#### A lot of simple selects on ranges #### A lot of simple selects on ranges
......
...@@ -45,7 +45,7 @@ class Field { ...@@ -45,7 +45,7 @@ class Field {
uint8 null_bit; // And position to it uint8 null_bit; // And position to it
struct st_table *table; // Pointer for table struct st_table *table; // Pointer for table
ulong query_id; // For quick test of used fields ulong query_id; // For quick test of used fields
key_map key_start,part_of_key; // Key is part of these keys. key_map key_start,part_of_key,part_of_sortkey;// Field is part of these keys.
const char *table_name,*field_name; const char *table_name,*field_name;
utype unireg_check; utype unireg_check;
uint32 field_length; // Length of field uint32 field_length; // Length of field
......
This diff is collapsed.
...@@ -736,7 +736,7 @@ ha_innobase::open( ...@@ -736,7 +736,7 @@ ha_innobase::open(
stored the string length as the first byte. */ stored the string length as the first byte. */
buff_len = table->reclength + table->max_key_length buff_len = table->reclength + table->max_key_length
+ MAX_REF_PARTS * 2; + MAX_REF_PARTS * 3;
if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME), if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
&upd_buff, buff_len, &upd_buff, buff_len,
&key_val_buff, buff_len, &key_val_buff, buff_len,
...@@ -2594,10 +2594,10 @@ ha_innobase::update_table_comment( ...@@ -2594,10 +2594,10 @@ ha_innobase::update_table_comment(
return (char*)comment; return (char*)comment;
sprintf(str, sprintf(str,
"%s; (See manual about Innobase stats); Innobase free: %lu kB", "%s; Innobase free: %lu kB",
comment, (ulong) innobase_get_free_space()); comment, (ulong) innobase_get_free_space());
return((char*) str); return(str);
} }
......
...@@ -221,6 +221,37 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, ...@@ -221,6 +221,37 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
return to; return to;
} }
void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
{
DBUG_ENTER("ha_myisammrg::update_create_info");
if (!(create_info->used_fields & HA_CREATE_USED_UNION))
{
MYRG_TABLE *table;
THD *thd=current_thd;
create_info->merge_list.next= &create_info->merge_list.first;
for (table=file->open_tables ; table != file->end_table ; table++)
{
char *name=table->table->s->filename;
char buff[FN_REFLEN];
TABLE_LIST *ptr;
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
goto err;
fn_format(buff,name,"","",3);
if (!(ptr->real_name=thd->strdup(buff)))
goto err;
(*create_info->merge_list.next) = (byte*) ptr;
create_info->merge_list.next= (byte**) &ptr->next;
}
*create_info->merge_list.next=0;
}
DBUG_VOID_RETURN;
err:
create_info->merge_list.elements=0;
create_info->merge_list.first=0;
DBUG_VOID_RETURN;
}
int ha_myisammrg::create(const char *name, register TABLE *form, int ha_myisammrg::create(const char *name, register TABLE *form,
HA_CREATE_INFO *create_info) HA_CREATE_INFO *create_info)
......
...@@ -72,5 +72,6 @@ class ha_myisammrg: public handler ...@@ -72,5 +72,6 @@ class ha_myisammrg: public handler
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type); enum thr_lock_type lock_type);
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet); void append_create_info(String *packet);
}; };
...@@ -133,6 +133,8 @@ int ha_init() ...@@ -133,6 +133,8 @@ int ha_init()
int error; int error;
if ((error=berkeley_init())) if ((error=berkeley_init()))
return error; return error;
if (!berkeley_skip) // If we couldn't use handler
opt_using_transactions=1;
} }
#endif #endif
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
...@@ -140,6 +142,8 @@ int ha_init() ...@@ -140,6 +142,8 @@ int ha_init()
{ {
if (innobase_init()) if (innobase_init())
return -1; return -1;
if (!innobase_skip) // If we couldn't use handler
opt_using_transactions=1;
} }
#endif #endif
return 0; return 0;
...@@ -190,13 +194,16 @@ int ha_autocommit_or_rollback(THD *thd, int error) ...@@ -190,13 +194,16 @@ int ha_autocommit_or_rollback(THD *thd, int error)
{ {
DBUG_ENTER("ha_autocommit_or_rollback"); DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
if (!error) if (opt_using_transactions)
{ {
if (ha_commit_stmt(thd)) if (!error)
error=1; {
if (ha_commit_stmt(thd))
error=1;
}
else
(void) ha_rollback_stmt(thd);
} }
else
(void) ha_rollback_stmt(thd);
#endif #endif
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -207,73 +214,80 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -207,73 +214,80 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
int error=0; int error=0;
DBUG_ENTER("ha_commit"); DBUG_ENTER("ha_commit");
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
/* Update the binary log if we have cached some queries */ if (opt_using_transactions)
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log))
{ {
mysql_bin_log.write(&thd->transaction.trans_log); /* Update the binary log if we have cached some queries */
reinit_io_cache(&thd->transaction.trans_log, if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
WRITE_CACHE, (my_off_t) 0, 0, 1); my_b_tell(&thd->transaction.trans_log))
thd->transaction.trans_log.end_of_file= max_binlog_cache_size; {
} mysql_bin_log.write(&thd->transaction.trans_log);
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid) if (trans->bdb_tid)
{
if ((error=berkeley_commit(thd,trans->bdb_tid)))
{ {
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); if ((error=berkeley_commit(thd,trans->bdb_tid)))
error=1; {
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
trans->bdb_tid=0;
} }
trans->bdb_tid=0;
}
#endif #endif
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
if (trans->innobase_tid) if (trans->innobase_tid)
{
if ((error=innobase_commit(thd,trans->innobase_tid)))
{ {
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); if ((error=innobase_commit(thd,trans->innobase_tid)))
error=1; {
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
} }
}
#endif #endif
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open()) if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
sql_print_error("Error: Got error during commit; Binlog is not up to date!"); sql_print_error("Error: Got error during commit; Binlog is not up to date!");
}
#endif // using transactions #endif // using transactions
DBUG_RETURN(error); DBUG_RETURN(error);
} }
int ha_rollback_trans(THD *thd, THD_TRANS *trans) int ha_rollback_trans(THD *thd, THD_TRANS *trans)
{ {
int error=0; int error=0;
DBUG_ENTER("ha_rollback"); DBUG_ENTER("ha_rollback");
#ifdef HAVE_BERKELEY_DB #ifdef USING_TRANSACTIONS
if (trans->bdb_tid) if (opt_using_transactions)
{ {
if ((error=berkeley_rollback(thd, trans->bdb_tid))) #ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
{ {
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); if ((error=berkeley_rollback(thd, trans->bdb_tid)))
error=1; {
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
trans->bdb_tid=0;
} }
trans->bdb_tid=0;
}
#endif #endif
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
if (trans->innobase_tid) if (trans->innobase_tid)
{
if ((error=innobase_rollback(thd, trans->innobase_tid)))
{ {
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); if ((error=innobase_rollback(thd, trans->innobase_tid)))
error=1; {
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
} }
}
#endif
#ifdef USING_TRANSACTIONS
if (trans == &thd->transaction.all)
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
#endif #endif
if (trans == &thd->transaction.all)
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -493,7 +507,10 @@ void handler::update_auto_increment() ...@@ -493,7 +507,10 @@ void handler::update_auto_increment()
THD *thd; THD *thd;
DBUG_ENTER("update_auto_increment"); DBUG_ENTER("update_auto_increment");
if (table->next_number_field->val_int() != 0) if (table->next_number_field->val_int() != 0)
{
auto_increment_column_changed=0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
}
thd=current_thd; thd=current_thd;
if ((nr=thd->next_insert_id)) if ((nr=thd->next_insert_id))
thd->next_insert_id=0; // Clear after use thd->next_insert_id=0; // Clear after use
...@@ -501,6 +518,7 @@ void handler::update_auto_increment() ...@@ -501,6 +518,7 @@ void handler::update_auto_increment()
nr=get_auto_increment(); nr=get_auto_increment();
thd->insert_id((ulonglong) nr); thd->insert_id((ulonglong) nr);
table->next_number_field->store(nr); table->next_number_field->store(nr);
auto_increment_column_changed=1;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -115,8 +115,9 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, ...@@ -115,8 +115,9 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
/* struct to hold information about the table that should be created */ /* struct to hold information about the table that should be created */
/* Bits in used_fields */ /* Bits in used_fields */
#define HA_CREATE_USED_AUTO 1 #define HA_CREATE_USED_AUTO 1
#define HA_CREATE_USED_RAID 2 #define HA_CREATE_USED_RAID 2
#define HA_CREATE_USED_UNION 4
typedef struct st_thd_trans { typedef struct st_thd_trans {
void *bdb_tid; void *bdb_tid;
...@@ -191,6 +192,7 @@ class handler :public Sql_alloc ...@@ -191,6 +192,7 @@ class handler :public Sql_alloc
time_t update_time; time_t update_time;
ulong mean_rec_length; /* physical reclength */ ulong mean_rec_length; /* physical reclength */
void *ft_handler; void *ft_handler;
bool auto_increment_column_changed;
handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS), handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS),
ref(0),ref_length(sizeof(my_off_t)), block_size(0),records(0),deleted(0), ref(0),ref_length(sizeof(my_off_t)), block_size(0),records(0),deleted(0),
......
...@@ -76,7 +76,7 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length) ...@@ -76,7 +76,7 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
KEY_PART_INFO *key_part; KEY_PART_INFO *key_part;
if (key_length == 0) if (key_length == 0)
key_length=key_info->key_length+key_info->extra_length; key_length=key_info->key_length;
for (key_part=key_info->key_part; for (key_part=key_info->key_part;
(int) key_length > 0 ; (int) key_length > 0 ;
key_part++) key_part++)
...@@ -122,7 +122,7 @@ void key_restore(TABLE *table,byte *key,uint idx,uint key_length) ...@@ -122,7 +122,7 @@ void key_restore(TABLE *table,byte *key,uint idx,uint key_length)
{ {
if (idx == (uint) -1) if (idx == (uint) -1)
return; return;
key_length=key_info->key_length+key_info->extra_length; key_length=key_info->key_length;
} }
for (key_part=key_info->key_part; for (key_part=key_info->key_part;
(int) key_length > 0 ; (int) key_length > 0 ;
......
...@@ -504,16 +504,16 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, ...@@ -504,16 +504,16 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_binlog_update, LOCK_slave, LOCK_server_id; LOCK_binlog_update, LOCK_slave, LOCK_server_id;
extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update, extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update,
COND_slave_stopped, COND_slave_start; COND_slave_stopped, COND_slave_start;
extern pthread_attr_t connection_attrib; extern pthread_attr_t connection_attrib;
extern bool opt_endinfo,using_udf_functions, locked_in_memory; extern bool opt_endinfo, using_udf_functions, locked_in_memory,
opt_using_transactions, use_temp_pool;
extern char f_fyllchar;
extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_key_count, ha_read_next_count, ha_read_prev_count,
ha_read_first_count, ha_read_last_count, ha_read_first_count, ha_read_last_count,
ha_read_rnd_count, ha_read_rnd_next_count; ha_read_rnd_count, ha_read_rnd_next_count;
extern MY_BITMAP temp_pool; extern MY_BITMAP temp_pool;
extern bool use_temp_pool;
extern char f_fyllchar;
extern uchar *days_in_month; extern uchar *days_in_month;
extern DATE_FORMAT dayord; extern DATE_FORMAT dayord;
extern double log_10[32]; extern double log_10[32];
......
...@@ -249,6 +249,7 @@ ulong max_tmp_tables,max_heap_table_size; ...@@ -249,6 +249,7 @@ ulong max_tmp_tables,max_heap_table_size;
ulong bytes_sent = 0L, bytes_received = 0L; ulong bytes_sent = 0L, bytes_received = 0L;
bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory;
bool opt_using_transactions;
bool volatile abort_loop,select_thread_in_use,grant_option; bool volatile abort_loop,select_thread_in_use,grant_option;
bool volatile ready_to_exit,shutdown_in_progress; bool volatile ready_to_exit,shutdown_in_progress;
ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */
......
...@@ -2500,14 +2500,16 @@ print_key(KEY_PART *key_part,const char *key,uint used_length) ...@@ -2500,14 +2500,16 @@ print_key(KEY_PART *key_part,const char *key,uint used_length)
fputc('/',DBUG_FILE); fputc('/',DBUG_FILE);
if (field->real_maybe_null()) if (field->real_maybe_null())
{ {
length++; length++; // null byte is not in part_length
if (*key++) if (*key++)
{ {
fwrite("NULL",sizeof(char),4,DBUG_FILE); fwrite("NULL",sizeof(char),4,DBUG_FILE);
continue; continue;
} }
} }
field->set_key_image((char*) key,key_part->part_length); field->set_key_image((char*) key,key_part->part_length -
((field->type() == FIELD_TYPE_BLOB) ?
HA_KEY_BLOB_LENGTH : 0));
field->val_str(&tmp,&tmp); field->val_str(&tmp,&tmp);
fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE); fwrite(tmp.ptr(),sizeof(char),tmp.length(),DBUG_FILE);
} }
......
...@@ -331,16 +331,15 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) ...@@ -331,16 +331,15 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond)
part != part_end ; part != part_end ;
part++) part++)
{ {
if (!part_of_cond(cond,part->field)) if (!part_of_cond(cond,part->field) ||
left_length < part->store_length)
break; break;
// Save found constant // Save found constant
if (part->null_bit) if (part->null_bit)
*key_ptr++= (byte) test(part->field->is_null()); *key_ptr++= (byte) test(part->field->is_null());
if (left_length - part->length < 0) part->field->get_key_image((char*) key_ptr,part->length);
break; // Can't use this key key_ptr+=part->store_length - test(part->null_bit);
part->field->get_image((char*) key_ptr,part->length); left_length-=part->store_length;
key_ptr+=part->length;
left_length-=part->length;
} }
if (part == part_end && part->field == field) if (part == part_end && part->field == field)
{ {
......
...@@ -91,7 +91,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -91,7 +91,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
tmp_table=0; tmp_table=0;
lock=locked_tables=0; lock=locked_tables=0;
used_tables=0; used_tables=0;
cuted_fields=0L; cuted_fields=sent_row_count=0L;
options=thd_startup_options; options=thd_startup_options;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE; update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
start_time=(time_t) 0; start_time=(time_t) 0;
...@@ -118,12 +118,15 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -118,12 +118,15 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
system_thread=0; system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root)); bzero((char*) &mem_root,sizeof(mem_root));
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction)); if (opt_using_transactions)
if (open_cached_file(&transaction.trans_log, {
mysql_tmpdir, LOG_PREFIX, binlog_cache_size, bzero((char*) &transaction,sizeof(transaction));
MYF(MY_WME))) if (open_cached_file(&transaction.trans_log,
killed=1; mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
transaction.trans_log.end_of_file= max_binlog_cache_size; MYF(MY_WME)))
killed=1;
transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif #endif
#ifdef __WIN__ #ifdef __WIN__
...@@ -148,8 +151,11 @@ THD::~THD() ...@@ -148,8 +151,11 @@ THD::~THD()
} }
close_temporary_tables(this); close_temporary_tables(this);
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
close_cached_file(&transaction.trans_log); if (opt_using_transactions)
ha_close_connection(this); {
close_cached_file(&transaction.trans_log);
ha_close_connection(this);
}
#endif #endif
if (global_read_lock) if (global_read_lock)
{ {
......
...@@ -346,6 +346,14 @@ int write_record(TABLE *table,COPY_INFO *info) ...@@ -346,6 +346,14 @@ int write_record(TABLE *table,COPY_INFO *info)
error=HA_WRITE_SKIPP; /* Database can't find key */ error=HA_WRITE_SKIPP; /* Database can't find key */
goto err; goto err;
} }
/*
Don't allow REPLACE to replace a row when a auto_increment column
was used. This ensures that we don't get a problem when the
whole range of the key has been used.
*/
if (table->next_number_field && key_nr == table->next_number_index &&
table->file->auto_increment_column_changed)
goto err;
if (table->file->option_flag() & HA_DUPP_POS) if (table->file->option_flag() & HA_DUPP_POS)
{ {
if (table->file->rnd_pos(table->record[1],table->file->dupp_ref)) if (table->file->rnd_pos(table->record[1],table->file->dupp_ref))
......
...@@ -156,7 +156,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, ...@@ -156,7 +156,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
{ {
bool error=test(mysql_change_db(thd,db)); bool error=test(mysql_change_db(thd,db));
if (error) if (error)
decrease_user_connections(user,thd->host); decrease_user_connections(thd->user,thd->host);
return error; return error;
} }
else else
...@@ -175,8 +175,8 @@ static DYNAMIC_ARRAY user_conn_array; ...@@ -175,8 +175,8 @@ static DYNAMIC_ARRAY user_conn_array;
extern pthread_mutex_t LOCK_user_conn; extern pthread_mutex_t LOCK_user_conn;
struct user_conn { struct user_conn {
char user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; char *user;
int connections, len; uint len, connections;
}; };
static byte* get_key_conn(user_conn *buff, uint *length, static byte* get_key_conn(user_conn *buff, uint *length,
...@@ -188,18 +188,23 @@ static byte* get_key_conn(user_conn *buff, uint *length, ...@@ -188,18 +188,23 @@ static byte* get_key_conn(user_conn *buff, uint *length,
#define DEF_USER_COUNT 50 #define DEF_USER_COUNT 50
static void free_user(struct user_conn *uc)
{
my_free((char*) uc,MYF(0));
}
void init_max_user_conn(void) void init_max_user_conn(void)
{ {
(void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0, (void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
(hash_get_key) get_key_conn,0, 0); (hash_get_key) get_key_conn, (void (*)(void*)) free_user,
(void) init_dynamic_array(&user_conn_array,sizeof(user_conn), 0);
DEF_USER_COUNT, DEF_USER_COUNT);
} }
static int check_for_max_user_connections(const char *user, int u_length, static int check_for_max_user_connections(const char *user, int u_length,
const char *host) const char *host)
{ {
int error=1;
uint temp_len; uint temp_len;
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
struct user_conn *uc; struct user_conn *uc;
...@@ -207,6 +212,9 @@ static int check_for_max_user_connections(const char *user, int u_length, ...@@ -207,6 +212,9 @@ static int check_for_max_user_connections(const char *user, int u_length,
user=""; user="";
if (!host) if (!host)
host=""; host="";
DBUG_ENTER("check_for_max_user_connections");
DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host, temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
NullS) - temp_user); NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn); (void) pthread_mutex_lock(&LOCK_user_conn);
...@@ -214,30 +222,40 @@ static int check_for_max_user_connections(const char *user, int u_length, ...@@ -214,30 +222,40 @@ static int check_for_max_user_connections(const char *user, int u_length,
(byte*) temp_user, temp_len); (byte*) temp_user, temp_len);
if (uc) /* user found ; check for no. of connections */ if (uc) /* user found ; check for no. of connections */
{ {
if ((uint) max_user_connections == uc->connections) if (max_user_connections == (uint) uc->connections)
{ {
net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user); net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user);
pthread_mutex_unlock(&LOCK_user_conn); goto end;
return 1;
} }
uc->connections++; uc->connections++;
} }
else else
{ {
/* the user is not found in the cache; Insert it */ /* the user is not found in the cache; Insert it */
struct user_conn uc; struct user_conn *uc= ((struct user_conn*)
memcpy(uc.user,temp_user,temp_len+1); my_malloc(sizeof(struct user_conn) + temp_len+1,
uc.len = temp_len; MYF(MY_WME)));
uc.connections = 1; if (!uc)
if (!insert_dynamic(&user_conn_array, (char *) &uc)) {
{ send_error(&current_thd->net, 0, NullS); // Out of memory
hash_insert(&hash_user_connections, goto end;
(byte *) dynamic_array_ptr(&user_conn_array, }
user_conn_array.elements - 1)); uc->user=(char*) (uc+1);
memcpy(uc->user,temp_user,temp_len+1);
uc->len = temp_len;
uc->connections = 1;
if (hash_insert(&hash_user_connections, (byte*) uc))
{
my_free((char*) uc,0);
send_error(&current_thd->net, 0, NullS); // Out of memory
goto end;
} }
} }
error=0;
end:
(void) pthread_mutex_unlock(&LOCK_user_conn); (void) pthread_mutex_unlock(&LOCK_user_conn);
return 0; DBUG_RETURN(error);
} }
...@@ -246,10 +264,15 @@ static void decrease_user_connections(const char *user, const char *host) ...@@ -246,10 +264,15 @@ static void decrease_user_connections(const char *user, const char *host)
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
int temp_len; int temp_len;
struct user_conn uucc, *uc; struct user_conn uucc, *uc;
if (!max_user_connections)
return;
if (!user) if (!user)
user=""; user="";
if (!host) if (!host)
host=""; host="";
DBUG_ENTER("decrease_user_connections");
DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host));
temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host, temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
NullS) - temp_user); NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn); (void) pthread_mutex_lock(&LOCK_user_conn);
...@@ -263,17 +286,15 @@ static void decrease_user_connections(const char *user, const char *host) ...@@ -263,17 +286,15 @@ static void decrease_user_connections(const char *user, const char *host)
{ {
/* Last connection for user; Delete it */ /* Last connection for user; Delete it */
(void) hash_delete(&hash_user_connections,(char *) uc); (void) hash_delete(&hash_user_connections,(char *) uc);
uint element= ((uint) ((byte*) uc - (byte*) user_conn_array.buffer) /
user_conn_array.size_of_element);
delete_dynamic_element(&user_conn_array,element);
} }
end: end:
(void) pthread_mutex_unlock(&LOCK_user_conn); (void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_VOID_RETURN;
} }
void free_max_user_conn(void) void free_max_user_conn(void)
{ {
delete_dynamic(&user_conn_array);
hash_free(&hash_user_connections); hash_free(&hash_user_connections);
} }
...@@ -336,20 +357,20 @@ check_connections(THD *thd) ...@@ -336,20 +357,20 @@ check_connections(THD *thd)
{ {
/* buff[] needs to big enough to hold the server_version variable */ /* buff[] needs to big enough to hold the server_version variable */
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end; char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end;
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB;
CLIENT_TRANSACTIONS; if (opt_using_transactions)
LINT_INIT(pkt_len); client_flags|=CLIENT_TRANSACTIONS;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
end=strmov(buff,server_version)+1; end=strmov(buff,server_version)+1;
int4store((uchar*) end,thd->thread_id); int4store((uchar*) end,thd->thread_id);
end+=4; end+=4;
memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1); memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
end+=SCRAMBLE_LENGTH +1; end+=SCRAMBLE_LENGTH +1;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (ssl_acceptor_fd!=0) if (ssl_acceptor_fd)
client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */ client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
/* /*
* Without SSL the handshake consists of one packet. This packet * Without SSL the handshake consists of one packet. This packet
...@@ -542,8 +563,7 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -542,8 +563,7 @@ pthread_handler_decl(handle_one_connection,arg)
thread_safe_increment(aborted_threads,&LOCK_thread_count); thread_safe_increment(aborted_threads,&LOCK_thread_count);
} }
if (max_user_connections) decrease_user_connections(thd->user,thd->host);
decrease_user_connections(thd->user,thd->host);
end_thread: end_thread:
close_connection(net); close_connection(net);
end_thread(thd,1); end_thread(thd,1);
...@@ -567,17 +587,18 @@ pthread_handler_decl(handle_bootstrap,arg) ...@@ -567,17 +587,18 @@ pthread_handler_decl(handle_bootstrap,arg)
THD *thd=(THD*) arg; THD *thd=(THD*) arg;
FILE *file=bootstrap_file; FILE *file=bootstrap_file;
char *buff; char *buff;
DBUG_ENTER("handle_bootstrap");
pthread_detach_this_thread();
thd->thread_stack= (char*) &thd;
/* The following must be called before DBUG_ENTER */
if (my_thread_init() || thd->store_globals()) if (my_thread_init() || thd->store_globals())
{ {
close_connection(&thd->net,ER_OUT_OF_RESOURCES); close_connection(&thd->net,ER_OUT_OF_RESOURCES);
thd->fatal_error=1; thd->fatal_error=1;
goto end; goto end;
} }
DBUG_ENTER("handle_bootstrap");
pthread_detach_this_thread();
thd->thread_stack= (char*) &thd;
thd->mysys_var=my_thread_var; thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id(); thd->dbug_thread_id=my_thread_id();
#ifndef __WIN__ #ifndef __WIN__
...@@ -2800,4 +2821,3 @@ static void refresh_status(void) ...@@ -2800,4 +2821,3 @@ static void refresh_status(void)
pthread_mutex_unlock(&LOCK_status); pthread_mutex_unlock(&LOCK_status);
pthread_mutex_unlock(&THR_LOCK_keycache); pthread_mutex_unlock(&THR_LOCK_keycache);
} }
...@@ -2037,8 +2037,7 @@ get_best_combination(JOIN *join) ...@@ -2037,8 +2037,7 @@ get_best_combination(JOIN *join)
if (keyparts == keyuse->keypart) if (keyparts == keyuse->keypart)
{ {
keyparts++; keyparts++;
length+=keyinfo->key_part[keyuse->keypart].length + length+=keyinfo->key_part[keyuse->keypart].store_length;
test(keyinfo->key_part[keyuse->keypart].null_bit);
} }
} }
keyuse++; keyuse++;
...@@ -2238,7 +2237,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -2238,7 +2237,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
make_cond_for_table(cond,join->const_table_map,(table_map) 0); make_cond_for_table(cond,join->const_table_map,(table_map) 0);
DBUG_EXECUTE("where",print_where(const_cond,"constants");); DBUG_EXECUTE("where",print_where(const_cond,"constants"););
if (const_cond && !const_cond->val_int()) if (const_cond && !const_cond->val_int())
{
DBUG_PRINT("info",("Found impossible WHERE condition"));
DBUG_RETURN(1); // Impossible const condition DBUG_RETURN(1); // Impossible const condition
}
} }
used_tables=(select->const_tables=join->const_table_map) | RAND_TABLE_BIT; used_tables=(select->const_tables=join->const_table_map) | RAND_TABLE_BIT;
for (uint i=join->const_tables ; i < join->tables ; i++) for (uint i=join->const_tables ; i < join->tables ; i++)
...@@ -5131,7 +5133,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) ...@@ -5131,7 +5133,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit)
usable_keys=0; usable_keys=0;
break; break;
} }
usable_keys&=((Item_field*) (*tmp_order->item))->field->part_of_key; usable_keys&=((Item_field*) (*tmp_order->item))->field->part_of_sortkey;
} }
ref_key= -1; ref_key= -1;
......
...@@ -740,6 +740,7 @@ create_table_option: ...@@ -740,6 +740,7 @@ create_table_option:
lex->table_list.elements=1; lex->table_list.elements=1;
lex->table_list.next= (byte**) &(table_list->next); lex->table_list.next= (byte**) &(table_list->next);
table_list->next=0; table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
} }
table_types: table_types:
...@@ -2666,8 +2667,11 @@ option_value: ...@@ -2666,8 +2667,11 @@ option_value:
{ {
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4); Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
if (item->fix_fields(current_thd,0) || item->update()) if (item->fix_fields(current_thd,0) || item->update())
{
send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY); send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
} YYABORT;
}
}
| SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM | SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
{ {
pthread_mutex_lock(&LOCK_slave); pthread_mutex_lock(&LOCK_slave);
......
...@@ -153,7 +153,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -153,7 +153,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (i=0 ; i < keys ; i++, keyinfo++) for (i=0 ; i < keys ; i++, keyinfo++)
{ {
uint null_parts=0;
keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME; keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
keyinfo->key_length= (uint) uint2korr(strpos+1); keyinfo->key_length= (uint) uint2korr(strpos+1);
keyinfo->key_parts= (uint) strpos[3]; strpos+=4; keyinfo->key_parts= (uint) strpos[3]; strpos+=4;
...@@ -185,7 +184,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -185,7 +184,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
} }
key_part->store_length=key_part->length; key_part->store_length=key_part->length;
} }
keyinfo->key_length+=null_parts;
set_if_bigger(outparam->max_key_length,keyinfo->key_length+ set_if_bigger(outparam->max_key_length,keyinfo->key_length+
keyinfo->key_parts); keyinfo->key_parts);
if (keyinfo->flags & HA_NOSAME) if (keyinfo->flags & HA_NOSAME)
...@@ -420,6 +418,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -420,6 +418,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
key_part->store_length+=HA_KEY_NULL_LENGTH; key_part->store_length+=HA_KEY_NULL_LENGTH;
keyinfo->flags|=HA_NULL_PART_KEY; keyinfo->flags|=HA_NULL_PART_KEY;
keyinfo->extra_length+= HA_KEY_NULL_LENGTH; keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
} }
if (field->type() == FIELD_TYPE_BLOB || if (field->type() == FIELD_TYPE_BLOB ||
field->real_type() == FIELD_TYPE_VAR_STRING) field->real_type() == FIELD_TYPE_VAR_STRING)
...@@ -428,6 +427,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -428,6 +427,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
key_part->key_part_flag|= HA_BLOB_PART; key_part->key_part_flag|= HA_BLOB_PART;
keyinfo->extra_length+=HA_KEY_BLOB_LENGTH; keyinfo->extra_length+=HA_KEY_BLOB_LENGTH;
key_part->store_length+=HA_KEY_BLOB_LENGTH; key_part->store_length+=HA_KEY_BLOB_LENGTH;
keyinfo->key_length+= HA_KEY_BLOB_LENGTH;
} }
if (i == 0 && key != primary_key) if (i == 0 && key != primary_key)
field->flags |= field->flags |=
...@@ -438,11 +438,16 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -438,11 +438,16 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
field->key_start|= ((key_map) 1 << key); field->key_start|= ((key_map) 1 << key);
if ((ha_option & HA_HAVE_KEY_READ_ONLY) && if ((ha_option & HA_HAVE_KEY_READ_ONLY) &&
field->key_length() == key_part->length && field->key_length() == key_part->length &&
field->type() != FIELD_TYPE_BLOB && field->type() != FIELD_TYPE_BLOB)
(field->key_type() != HA_KEYTYPE_TEXT || {
(!(ha_option & HA_KEY_READ_WRONG_STR) && if (field->key_type() != HA_KEYTYPE_TEXT ||
!(keyinfo->flags & HA_FULLTEXT)))) (!(ha_option & HA_KEY_READ_WRONG_STR) &&
field->part_of_key|= ((key_map) 1 << key); !(keyinfo->flags & HA_FULLTEXT)))
field->part_of_key|= ((key_map) 1 << key);
if (field->key_type() != HA_KEYTYPE_TEXT ||
!(keyinfo->flags & HA_FULLTEXT))
field->part_of_sortkey|= ((key_map) 1 << key);
}
if (!(key_part->key_part_flag & HA_REVERSE_SORT) && if (!(key_part->key_part_flag & HA_REVERSE_SORT) &&
usable_parts == i) usable_parts == i)
usable_parts++; // For FILESORT usable_parts++; // For FILESORT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment