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)
else
ds= &ds_res;
if((flags & QUERY_SEND) &&
(q_error = mysql_send_query(mysql, q->query)))
if ((flags & QUERY_SEND) &&
(q_error = mysql_send_query(mysql, q->query, strlen(q->query))))
die("At line %u: unable to send query '%s'", start_lineno, q->query);
if(!(flags & QUERY_REAP))
return 0;
if (mysql_reap_query(mysql))
if (mysql_read_query_result(mysql))
{
if (q->require_file)
abort_not_supported_test();
......
......@@ -229,12 +229,11 @@ MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host,
void STDCALL mysql_close(MYSQL *sock);
int STDCALL mysql_select_db(MYSQL *mysql, const char *db);
int STDCALL mysql_query(MYSQL *mysql, const char *q);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q);
int STDCALL mysql_reap_query(MYSQL *mysql);
int STDCALL mysql_send_query(MYSQL *mysql, const char *q,
unsigned int length);
int STDCALL mysql_read_query_result(MYSQL *mysql);
int STDCALL mysql_real_query(MYSQL *mysql, const char *q,
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_drop_db(MYSQL *mysql, const char *DB);
int STDCALL mysql_shutdown(MYSQL *mysql);
......
......@@ -1700,87 +1700,30 @@ mysql_query(MYSQL *mysql, const char *query)
return mysql_real_query(mysql,query, (uint) strlen(query));
}
int STDCALL
mysql_send_query(MYSQL* mysql, const char* query)
{
return mysql_real_send_query(mysql, query, strlen(query));
}
/* 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
/*
Send the query and return so we can do something else.
Needs to be followed by mysql_read_query_result() 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
mysql_reap_query(MYSQL* mysql)
mysql_send_query(MYSQL* mysql, const char* query, uint length)
{
uchar *pos;
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);
return simple_command(mysql, COM_QUERY, query, length, 1);
}
int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length)
int STDCALL mysql_read_query_result(MYSQL *mysql)
{
uchar *pos;
ulong field_count;
MYSQL_DATA *fields;
DBUG_ENTER("mysql_real_query");
DBUG_PRINT("enter",("handle: %lx",mysql));
DBUG_PRINT("query",("Query = \"%s\"",query));
uint length;
DBUG_ENTER("mysql_read_query_result");
if (simple_command(mysql,COM_QUERY,query,length,1) ||
(length=net_safe_read(mysql)) == packet_error)
if ((length = net_safe_read(mysql)) == packet_error)
DBUG_RETURN(-1);
free_old_query(mysql); /* Free old result */
get_info:
get_info:
pos=(uchar*) mysql->net.read_pos;
if ((field_count= net_field_length(&pos)) == 0)
{
......@@ -1817,6 +1760,16 @@ mysql_real_query(MYSQL *mysql, const char *query, uint length)
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
send_file_to_server(MYSQL *mysql, const char *filename)
......
......@@ -483,3 +483,10 @@ i j
1 2
build_path
current
a b
a 2
a b
a 2
a b
a 1
a 2
......@@ -120,14 +120,14 @@ UserId
b
1
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
t1 eq_ref PRIMARY PRIMARY 4 t2.a 1 where used; Distinct
a
1
table type possible_keys key key_len ref rows Extra
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
1
2
......
......@@ -10,3 +10,10 @@ name_id name
name_id name
name_id name
2 [T,U]_axpby
a b
a 2
a b
a 2
a b
a 1
a 2
......@@ -103,9 +103,6 @@ test2
test2
c
c
test1
test1
test1
incr othr
incr othr
1 10
......@@ -118,4 +115,15 @@ count(*)
20
count(*)
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
......@@ -728,3 +728,18 @@ where
t3.platform_id = 2;
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');
INSERT INTO t1 VALUES (1, 1, 1, 1, 'b');
!$1062 INSERT INTO t1 VALUES (1, 1, 1, 1, 'a');
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');
insert into t2 (c) values ('test2');
select * from t3;
select * from t3;
delete from t3;
delete from t3 where 1=1;
select * from t3;
select * from t1;
drop table t3,t2,t1;
......@@ -78,6 +78,16 @@ alter table t3 UNION=(t1,t2);
select count(*) from t3;
alter table t3 TYPE=MYISAM;
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;
#
......
......@@ -20,3 +20,17 @@ replace into t1 (gesuchnr,benutzer_id) values (1,1);
alter table t1 type=heap;
replace into t1 (gesuchnr,benutzer_id) values (1,1);
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 @@
#define INCL_BASE
#define INCL_NOPMAPI
#include <os2emx.h>
#endif
#ifndef __EMX__
#ifdef HAVE_FCNTL
static struct flock lock; /* Must be static for sun-sparc */
#endif
#endif
/* 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,
}
#else
#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 */
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;
struct flock lock;
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 */
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;
if (value != -1)
else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
DBUG_RETURN(0);
if (errno == EINTR)
errno=EAGAIN;
}
else if (fcntl(fd,F_SETLKW,&lock) != -1) /* Wait until a lock */
DBUG_RETURN(0);
#else
if (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");
# Check reading on direct key on id and id3
check_select_key("id","select_key_prefix");
check_select_key2("id","id2","select_key");
check_select_key("id3","select_key2");
check_select_key("*","id","select_key_prefix");
check_select_key2("*","id","id2","select_key");
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
......
......@@ -45,7 +45,7 @@ class Field {
uint8 null_bit; // And position to it
struct st_table *table; // Pointer for table
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;
utype unireg_check;
uint32 field_length; // Length of field
......
This diff is collapsed.
......@@ -736,7 +736,7 @@ ha_innobase::open(
stored the string length as the first byte. */
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),
&upd_buff, buff_len,
&key_val_buff, buff_len,
......@@ -2594,10 +2594,10 @@ ha_innobase::update_table_comment(
return (char*)comment;
sprintf(str,
"%s; (See manual about Innobase stats); Innobase free: %lu kB",
"%s; Innobase free: %lu kB",
comment, (ulong) innobase_get_free_space());
return((char*) str);
return(str);
}
......
......@@ -221,6 +221,37 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd,
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,
HA_CREATE_INFO *create_info)
......
......@@ -72,5 +72,6 @@ class ha_myisammrg: public handler
int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
enum thr_lock_type lock_type);
void update_create_info(HA_CREATE_INFO *create_info);
void append_create_info(String *packet);
};
......@@ -133,6 +133,8 @@ int ha_init()
int error;
if ((error=berkeley_init()))
return error;
if (!berkeley_skip) // If we couldn't use handler
opt_using_transactions=1;
}
#endif
#ifdef HAVE_INNOBASE_DB
......@@ -140,6 +142,8 @@ int ha_init()
{
if (innobase_init())
return -1;
if (!innobase_skip) // If we couldn't use handler
opt_using_transactions=1;
}
#endif
return 0;
......@@ -190,13 +194,16 @@ int ha_autocommit_or_rollback(THD *thd, int error)
{
DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef USING_TRANSACTIONS
if (!error)
if (opt_using_transactions)
{
if (ha_commit_stmt(thd))
error=1;
if (!error)
{
if (ha_commit_stmt(thd))
error=1;
}
else
(void) ha_rollback_stmt(thd);
}
else
(void) ha_rollback_stmt(thd);
#endif
DBUG_RETURN(error);
}
......@@ -207,73 +214,80 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
int error=0;
DBUG_ENTER("ha_commit");
#ifdef USING_TRANSACTIONS
/* Update the binary log if we have cached some queries */
if (trans == &thd->transaction.all && mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log))
if (opt_using_transactions)
{
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;
}
/* Update the binary log if we have cached some queries */
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);
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
if (trans->bdb_tid)
{
if ((error=berkeley_commit(thd,trans->bdb_tid)))
if (trans->bdb_tid)
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
if ((error=berkeley_commit(thd,trans->bdb_tid)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
trans->bdb_tid=0;
}
trans->bdb_tid=0;
}
#endif
#ifdef HAVE_INNOBASE_DB
if (trans->innobase_tid)
{
if ((error=innobase_commit(thd,trans->innobase_tid)))
if (trans->innobase_tid)
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
if ((error=innobase_commit(thd,trans->innobase_tid)))
{
my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
error=1;
}
}
}
#endif
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!");
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!");
}
#endif // using transactions
DBUG_RETURN(error);
}
int ha_rollback_trans(THD *thd, THD_TRANS *trans)
{
int error=0;
DBUG_ENTER("ha_rollback");
#ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
#ifdef USING_TRANSACTIONS
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);
error=1;
if ((error=berkeley_rollback(thd, trans->bdb_tid)))
{
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
trans->bdb_tid=0;
}
trans->bdb_tid=0;
}
#endif
#ifdef HAVE_INNOBASE_DB
if (trans->innobase_tid)
{
if ((error=innobase_rollback(thd, trans->innobase_tid)))
if (trans->innobase_tid)
{
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
if ((error=innobase_rollback(thd, trans->innobase_tid)))
{
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
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);
}
......@@ -493,7 +507,10 @@ void handler::update_auto_increment()
THD *thd;
DBUG_ENTER("update_auto_increment");
if (table->next_number_field->val_int() != 0)
{
auto_increment_column_changed=0;
DBUG_VOID_RETURN;
}
thd=current_thd;
if ((nr=thd->next_insert_id))
thd->next_insert_id=0; // Clear after use
......@@ -501,6 +518,7 @@ void handler::update_auto_increment()
nr=get_auto_increment();
thd->insert_id((ulonglong) nr);
table->next_number_field->store(nr);
auto_increment_column_changed=1;
DBUG_VOID_RETURN;
}
......
......@@ -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 */
/* Bits in used_fields */
#define HA_CREATE_USED_AUTO 1
#define HA_CREATE_USED_RAID 2
#define HA_CREATE_USED_AUTO 1
#define HA_CREATE_USED_RAID 2
#define HA_CREATE_USED_UNION 4
typedef struct st_thd_trans {
void *bdb_tid;
......@@ -191,6 +192,7 @@ class handler :public Sql_alloc
time_t update_time;
ulong mean_rec_length; /* physical reclength */
void *ft_handler;
bool auto_increment_column_changed;
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),
......
......@@ -76,7 +76,7 @@ void key_copy(byte *key,TABLE *table,uint idx,uint key_length)
KEY_PART_INFO *key_part;
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;
(int) key_length > 0 ;
key_part++)
......@@ -122,7 +122,7 @@ void key_restore(TABLE *table,byte *key,uint idx,uint key_length)
{
if (idx == (uint) -1)
return;
key_length=key_info->key_length+key_info->extra_length;
key_length=key_info->key_length;
}
for (key_part=key_info->key_part;
(int) key_length > 0 ;
......
......@@ -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_binlog_update, LOCK_slave, LOCK_server_id;
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 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,
ha_read_key_count, ha_read_next_count, ha_read_prev_count,
ha_read_first_count, ha_read_last_count,
ha_read_rnd_count, ha_read_rnd_next_count;
extern MY_BITMAP temp_pool;
extern bool use_temp_pool;
extern char f_fyllchar;
extern uchar *days_in_month;
extern DATE_FORMAT dayord;
extern double log_10[32];
......
......@@ -249,6 +249,7 @@ ulong max_tmp_tables,max_heap_table_size;
ulong bytes_sent = 0L, bytes_received = 0L;
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 ready_to_exit,shutdown_in_progress;
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)
fputc('/',DBUG_FILE);
if (field->real_maybe_null())
{
length++;
length++; // null byte is not in part_length
if (*key++)
{
fwrite("NULL",sizeof(char),4,DBUG_FILE);
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);
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)
part != part_end ;
part++)
{
if (!part_of_cond(cond,part->field))
if (!part_of_cond(cond,part->field) ||
left_length < part->store_length)
break;
// Save found constant
if (part->null_bit)
*key_ptr++= (byte) test(part->field->is_null());
if (left_length - part->length < 0)
break; // Can't use this key
part->field->get_image((char*) key_ptr,part->length);
key_ptr+=part->length;
left_length-=part->length;
part->field->get_key_image((char*) key_ptr,part->length);
key_ptr+=part->store_length - test(part->null_bit);
left_length-=part->store_length;
}
if (part == part_end && part->field == field)
{
......
......@@ -91,7 +91,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
tmp_table=0;
lock=locked_tables=0;
used_tables=0;
cuted_fields=0L;
cuted_fields=sent_row_count=0L;
options=thd_startup_options;
update_lock_default= low_priority_updates ? TL_WRITE_LOW_PRIORITY : TL_WRITE;
start_time=(time_t) 0;
......@@ -118,12 +118,15 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
system_thread=0;
bzero((char*) &mem_root,sizeof(mem_root));
#ifdef USING_TRANSACTIONS
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME)))
killed=1;
transaction.trans_log.end_of_file= max_binlog_cache_size;
if (opt_using_transactions)
{
bzero((char*) &transaction,sizeof(transaction));
if (open_cached_file(&transaction.trans_log,
mysql_tmpdir, LOG_PREFIX, binlog_cache_size,
MYF(MY_WME)))
killed=1;
transaction.trans_log.end_of_file= max_binlog_cache_size;
}
#endif
#ifdef __WIN__
......@@ -148,8 +151,11 @@ THD::~THD()
}
close_temporary_tables(this);
#ifdef USING_TRANSACTIONS
close_cached_file(&transaction.trans_log);
ha_close_connection(this);
if (opt_using_transactions)
{
close_cached_file(&transaction.trans_log);
ha_close_connection(this);
}
#endif
if (global_read_lock)
{
......
......@@ -346,6 +346,14 @@ int write_record(TABLE *table,COPY_INFO *info)
error=HA_WRITE_SKIPP; /* Database can't find key */
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->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,
{
bool error=test(mysql_change_db(thd,db));
if (error)
decrease_user_connections(user,thd->host);
decrease_user_connections(thd->user,thd->host);
return error;
}
else
......@@ -175,8 +175,8 @@ static DYNAMIC_ARRAY user_conn_array;
extern pthread_mutex_t LOCK_user_conn;
struct user_conn {
char user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
int connections, len;
char *user;
uint len, connections;
};
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
static void free_user(struct user_conn *uc)
{
my_free((char*) uc,MYF(0));
}
void init_max_user_conn(void)
{
(void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
(hash_get_key) get_key_conn,0, 0);
(void) init_dynamic_array(&user_conn_array,sizeof(user_conn),
DEF_USER_COUNT, DEF_USER_COUNT);
(hash_get_key) get_key_conn, (void (*)(void*)) free_user,
0);
}
static int check_for_max_user_connections(const char *user, int u_length,
const char *host)
{
int error=1;
uint temp_len;
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
struct user_conn *uc;
......@@ -207,6 +212,9 @@ static int check_for_max_user_connections(const char *user, int u_length,
user="";
if (!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,
NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
......@@ -214,30 +222,40 @@ static int check_for_max_user_connections(const char *user, int u_length,
(byte*) temp_user, temp_len);
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);
pthread_mutex_unlock(&LOCK_user_conn);
return 1;
goto end;
}
uc->connections++;
}
else
{
/* the user is not found in the cache; Insert it */
struct user_conn uc;
memcpy(uc.user,temp_user,temp_len+1);
uc.len = temp_len;
uc.connections = 1;
if (!insert_dynamic(&user_conn_array, (char *) &uc))
{
hash_insert(&hash_user_connections,
(byte *) dynamic_array_ptr(&user_conn_array,
user_conn_array.elements - 1));
struct user_conn *uc= ((struct user_conn*)
my_malloc(sizeof(struct user_conn) + temp_len+1,
MYF(MY_WME)));
if (!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))
{
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);
return 0;
DBUG_RETURN(error);
}
......@@ -246,10 +264,15 @@ static void decrease_user_connections(const char *user, const char *host)
char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
int temp_len;
struct user_conn uucc, *uc;
if (!max_user_connections)
return;
if (!user)
user="";
if (!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,
NullS) - temp_user);
(void) pthread_mutex_lock(&LOCK_user_conn);
......@@ -263,17 +286,15 @@ static void decrease_user_connections(const char *user, const char *host)
{
/* Last connection for user; Delete it */
(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:
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_VOID_RETURN;
}
void free_max_user_conn(void)
{
delete_dynamic(&user_conn_array);
hash_free(&hash_user_connections);
}
......@@ -336,20 +357,20 @@ check_connections(THD *thd)
{
/* buff[] needs to big enough to hold the server_version variable */
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end;
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB |
CLIENT_TRANSACTIONS;
LINT_INIT(pkt_len);
int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB;
if (opt_using_transactions)
client_flags|=CLIENT_TRANSACTIONS;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
end=strmov(buff,server_version)+1;
int4store((uchar*) end,thd->thread_id);
end+=4;
memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
end+=SCRAMBLE_LENGTH +1;
#ifdef HAVE_COMPRESS
client_flags |= CLIENT_COMPRESS;
#endif /* HAVE_COMPRESS */
#ifdef HAVE_OPENSSL
if (ssl_acceptor_fd!=0)
if (ssl_acceptor_fd)
client_flags |= CLIENT_SSL; /* Wow, SSL is avalaible! */
/*
* Without SSL the handshake consists of one packet. This packet
......@@ -542,8 +563,7 @@ pthread_handler_decl(handle_one_connection,arg)
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:
close_connection(net);
end_thread(thd,1);
......@@ -567,17 +587,18 @@ pthread_handler_decl(handle_bootstrap,arg)
THD *thd=(THD*) arg;
FILE *file=bootstrap_file;
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())
{
close_connection(&thd->net,ER_OUT_OF_RESOURCES);
thd->fatal_error=1;
goto end;
}
DBUG_ENTER("handle_bootstrap");
pthread_detach_this_thread();
thd->thread_stack= (char*) &thd;
thd->mysys_var=my_thread_var;
thd->dbug_thread_id=my_thread_id();
#ifndef __WIN__
......@@ -2800,4 +2821,3 @@ static void refresh_status(void)
pthread_mutex_unlock(&LOCK_status);
pthread_mutex_unlock(&THR_LOCK_keycache);
}
......@@ -2037,8 +2037,7 @@ get_best_combination(JOIN *join)
if (keyparts == keyuse->keypart)
{
keyparts++;
length+=keyinfo->key_part[keyuse->keypart].length +
test(keyinfo->key_part[keyuse->keypart].null_bit);
length+=keyinfo->key_part[keyuse->keypart].store_length;
}
}
keyuse++;
......@@ -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);
DBUG_EXECUTE("where",print_where(const_cond,"constants"););
if (const_cond && !const_cond->val_int())
{
DBUG_PRINT("info",("Found impossible WHERE condition"));
DBUG_RETURN(1); // Impossible const condition
}
}
used_tables=(select->const_tables=join->const_table_map) | RAND_TABLE_BIT;
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)
usable_keys=0;
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;
......
......@@ -740,6 +740,7 @@ create_table_option:
lex->table_list.elements=1;
lex->table_list.next= (byte**) &(table_list->next);
table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
}
table_types:
......@@ -2666,8 +2667,11 @@ option_value:
{
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
if (item->fix_fields(current_thd,0) || item->update())
{
send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
}
YYABORT;
}
}
| SQL_SLAVE_SKIP_COUNTER equal ULONG_NUM
{
pthread_mutex_lock(&LOCK_slave);
......
......@@ -153,7 +153,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
for (i=0 ; i < keys ; i++, keyinfo++)
{
uint null_parts=0;
keyinfo->flags= ((uint) strpos[0]) ^ HA_NOSAME;
keyinfo->key_length= (uint) uint2korr(strpos+1);
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,
}
key_part->store_length=key_part->length;
}
keyinfo->key_length+=null_parts;
set_if_bigger(outparam->max_key_length,keyinfo->key_length+
keyinfo->key_parts);
if (keyinfo->flags & HA_NOSAME)
......@@ -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;
keyinfo->flags|=HA_NULL_PART_KEY;
keyinfo->extra_length+= HA_KEY_NULL_LENGTH;
keyinfo->key_length+= HA_KEY_NULL_LENGTH;
}
if (field->type() == FIELD_TYPE_BLOB ||
field->real_type() == FIELD_TYPE_VAR_STRING)
......@@ -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;
keyinfo->extra_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)
field->flags |=
......@@ -438,11 +438,16 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
field->key_start|= ((key_map) 1 << key);
if ((ha_option & HA_HAVE_KEY_READ_ONLY) &&
field->key_length() == key_part->length &&
field->type() != FIELD_TYPE_BLOB &&
(field->key_type() != HA_KEYTYPE_TEXT ||
(!(ha_option & HA_KEY_READ_WRONG_STR) &&
!(keyinfo->flags & HA_FULLTEXT))))
field->part_of_key|= ((key_map) 1 << key);
field->type() != FIELD_TYPE_BLOB)
{
if (field->key_type() != HA_KEYTYPE_TEXT ||
(!(ha_option & HA_KEY_READ_WRONG_STR) &&
!(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) &&
usable_parts == i)
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