Commit 869c89fe authored by unknown's avatar unknown

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.


Docs/manual.texi:
  Added some examples and moved the Error access denied section to the
  error section.
client/mysqltest.c:
  Changed to use the new mysql_send_query()
include/mysql.h:
  Changed mysql_reap_query() to mysql_send_query().
libmysql/libmysql.c:
  Changed mysql_reap_query() to mysql_send_query()
  Merged some functions and removed some unused functions.
mysql-test/r/bdb.result:
  New test case
mysql-test/r/distinct.result:
  New test case
mysql-test/r/key.result:
  New test case
mysql-test/r/merge.result:
  New test case
mysql-test/r/replace.result:
  New test case
mysql-test/t/bdb.test:
  New test case
mysql-test/t/key.test:
  New test case
mysql-test/t/merge.test:
  New test case
mysql-test/t/replace.test:
  New test case
mysys/my_lock.c:
  Moved global lock variable to static
sql-bench/test-insert.sh:
  Added test case for index-read only
sql/field.h:
  Fixed that one can optimize ORDER BY with ISAM and GEMINI
sql/ha_berkeley.cc:
  Added type casts needed for Windows
sql/ha_innobase.cc:
  Removed reference to manual from comment.
sql/ha_myisammrg.cc:
  Remember UNION for ALTER TABLE
sql/ha_myisammrg.h:
  Remember UNION for ALTER TABLE
sql/handler.cc:
  Added test for if we are supporting transactions.
  Don't allow REPLACE to replace a row when we have generated an auto_increment key.
sql/handler.h:
  Remember UNION for ALTER TABLE
sql/key.cc:
  Fixed bug when using BLOB keys
sql/mysql_priv.h:
  Added new variables
sql/mysqld.cc:
  Added new variables
sql/opt_range.cc:
  Fixed problem with BLOB keys
sql/opt_sum.cc:
  Fix for BLOB keys
sql/sql_class.cc:
  Added test if we need to init/clean transaction variables
sql/sql_insert.cc:
  Fix for REPLACE and auto_increment keys
sql/sql_parse.cc:
  Fixed bug in max_user_connections
sql/sql_select.cc:
  Fixed problem with key on BLOB
sql/sql_yacc.yy:
  Fixed bug in SET @variable=user.
sql/table.cc:
  Fixed problem with keys on BLOB
parent ec5e2f58
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,35 +1700,30 @@ mysql_query(MYSQL *mysql, const char *query) ...@@ -1700,35 +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 int STDCALL
mysql_real_send_query(MYSQL* mysql, const char* query, uint len) mysql_send_query(MYSQL* mysql, const char* query, uint length)
{ {
return simple_command(mysql, COM_QUERY, query, len, 1); return simple_command(mysql, COM_QUERY, query, length, 1);
} }
int STDCALL int STDCALL mysql_read_query_result(MYSQL *mysql)
mysql_reap_query(MYSQL* mysql)
{ {
uchar *pos; uchar *pos;
ulong field_count; ulong field_count;
MYSQL_DATA *fields; MYSQL_DATA *fields;
uint len; uint length;
DBUG_ENTER("mysql_reap_query"); DBUG_ENTER("mysql_read_query_result");
DBUG_PRINT("enter",("handle: %lx",mysql));
if((len = net_safe_read(mysql)) == packet_error) if ((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)
{ {
...@@ -1738,14 +1733,14 @@ mysql_reap_query(MYSQL* mysql) ...@@ -1738,14 +1733,14 @@ mysql_reap_query(MYSQL* mysql)
{ {
mysql->server_status=uint2korr(pos); pos+=2; mysql->server_status=uint2korr(pos); pos+=2;
} }
if (pos < mysql->net.read_pos+len && net_field_length(&pos)) if (pos < mysql->net.read_pos+length && net_field_length(&pos))
mysql->info=(char*) pos; mysql->info=(char*) pos;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */
{ {
int error=send_file_to_server(mysql,(char*) pos); int error=send_file_to_server(mysql,(char*) pos);
if ((len=net_safe_read(mysql)) == packet_error || error) if ((length=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(-1); DBUG_RETURN(-1);
goto get_info; /* Get info packet */ goto get_info; /* Get info packet */
} }
...@@ -1763,61 +1758,19 @@ mysql_reap_query(MYSQL* mysql) ...@@ -1763,61 +1758,19 @@ mysql_reap_query(MYSQL* mysql)
mysql->status=MYSQL_STATUS_GET_RESULT; mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count; mysql->field_count=field_count;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int STDCALL int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length) mysql_real_query(MYSQL *mysql, const char *query, uint length)
{ {
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
DBUG_ENTER("mysql_real_query"); DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql)); DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query)); DBUG_PRINT("query",("Query = \"%s\"",query));
if (simple_command(mysql,COM_QUERY,query,length,1))
if (simple_command(mysql,COM_QUERY,query,length,1) ||
(length=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+length && 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 ((length=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); DBUG_RETURN(-1);
if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, DBUG_RETURN(mysql_read_query_result(mysql));
(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);
} }
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,6 +118,8 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, ...@@ -124,6 +118,8 @@ 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)
{
struct flock lock;
lock.l_type= (short) locktype; lock.l_type= (short) locktype;
lock.l_whence=0L; lock.l_whence=0L;
lock.l_start=(long) start; lock.l_start=(long) start;
...@@ -147,6 +143,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, ...@@ -147,6 +143,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
} }
else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */ else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
DBUG_RETURN(0); 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,6 +194,8 @@ int ha_autocommit_or_rollback(THD *thd, int error) ...@@ -190,6 +194,8 @@ 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 (opt_using_transactions)
{
if (!error) if (!error)
{ {
if (ha_commit_stmt(thd)) if (ha_commit_stmt(thd))
...@@ -197,6 +203,7 @@ int ha_autocommit_or_rollback(THD *thd, int error) ...@@ -197,6 +203,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
} }
else else
(void) ha_rollback_stmt(thd); (void) ha_rollback_stmt(thd);
}
#endif #endif
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -207,6 +214,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -207,6 +214,8 @@ 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
if (opt_using_transactions)
{
/* Update the binary log if we have cached some queries */ /* Update the binary log if we have cached some queries */
if (trans == &thd->transaction.all && mysql_bin_log.is_open() && if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log)) my_b_tell(&thd->transaction.trans_log))
...@@ -239,14 +248,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) ...@@ -239,14 +248,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#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 USING_TRANSACTIONS
if (opt_using_transactions)
{
#ifdef HAVE_BERKELEY_DB #ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid) if (trans->bdb_tid)
{ {
...@@ -268,12 +282,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) ...@@ -268,12 +282,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
} }
} }
#endif #endif
#ifdef USING_TRANSACTIONS
if (trans == &thd->transaction.all) if (trans == &thd->transaction.all)
reinit_io_cache(&thd->transaction.trans_log, reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1); WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size; thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
#endif }
#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;
} }
......
...@@ -117,6 +117,7 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, ...@@ -117,6 +117,7 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
/* 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 ;
......
...@@ -506,14 +506,14 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, ...@@ -506,14 +506,14 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
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
if (opt_using_transactions)
{
bzero((char*) &transaction,sizeof(transaction)); bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log, if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size, mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME))) MYF(MY_WME)))
killed=1; killed=1;
transaction.trans_log.end_of_file= max_binlog_cache_size; 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
if (opt_using_transactions)
{
close_cached_file(&transaction.trans_log); close_cached_file(&transaction.trans_log);
ha_close_connection(this); 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
goto end;
}
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))
{ {
hash_insert(&hash_user_connections, my_free((char*) uc,0);
(byte *) dynamic_array_ptr(&user_conn_array, send_error(&current_thd->net, 0, NullS); // Out of memory
user_conn_array.elements - 1)); 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,7 +563,6 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -542,7 +563,6 @@ 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);
...@@ -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,8 +2237,11 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -2238,8 +2237,11 @@ 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,7 +2667,10 @@ option_value: ...@@ -2666,7 +2667,10 @@ 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
{ {
......
...@@ -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 || {
if (field->key_type() != HA_KEYTYPE_TEXT ||
(!(ha_option & HA_KEY_READ_WRONG_STR) && (!(ha_option & HA_KEY_READ_WRONG_STR) &&
!(keyinfo->flags & HA_FULLTEXT)))) !(keyinfo->flags & HA_FULLTEXT)))
field->part_of_key|= ((key_map) 1 << key); 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