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)
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,35 +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)
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
mysql_reap_query(MYSQL* mysql)
int STDCALL mysql_read_query_result(MYSQL *mysql)
{
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)
uint length;
DBUG_ENTER("mysql_read_query_result");
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)
{
......@@ -1738,14 +1733,14 @@ mysql_reap_query(MYSQL* mysql)
{
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;
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)
if ((length=net_safe_read(mysql)) == packet_error || error)
DBUG_RETURN(-1);
goto get_info; /* Get info packet */
}
......@@ -1763,61 +1758,19 @@ mysql_reap_query(MYSQL* mysql)
mysql->status=MYSQL_STATUS_GET_RESULT;
mysql->field_count=field_count;
DBUG_RETURN(0);
}
int STDCALL
mysql_real_query(MYSQL *mysql, const char *query, uint length)
{
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));
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)))
if (simple_command(mysql,COM_QUERY,query,length,1))
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);
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,6 +118,8 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
}
#else
#if defined(HAVE_FCNTL)
{
struct flock lock;
lock.l_type= (short) locktype;
lock.l_whence=0L;
lock.l_start=(long) start;
......@@ -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 */
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 @@ public:
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,6 +194,8 @@ int ha_autocommit_or_rollback(THD *thd, int error)
{
DBUG_ENTER("ha_autocommit_or_rollback");
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
if (!error)
{
if (ha_commit_stmt(thd))
......@@ -197,6 +203,7 @@ int ha_autocommit_or_rollback(THD *thd, int error)
}
else
(void) ha_rollback_stmt(thd);
}
#endif
DBUG_RETURN(error);
}
......@@ -207,6 +214,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
int error=0;
DBUG_ENTER("ha_commit");
#ifdef USING_TRANSACTIONS
if (opt_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))
......@@ -239,14 +248,19 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
#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!");
}
#endif // using transactions
DBUG_RETURN(error);
}
int ha_rollback_trans(THD *thd, THD_TRANS *trans)
{
int error=0;
DBUG_ENTER("ha_rollback");
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
#ifdef HAVE_BERKELEY_DB
if (trans->bdb_tid)
{
......@@ -268,12 +282,12 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
}
}
#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 /* 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;
}
......
......@@ -117,6 +117,7 @@ enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC,
/* Bits in used_fields */
#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 @@ public:
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 ;
......
......@@ -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,
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
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
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))
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))
{
hash_insert(&hash_user_connections,
(byte *) dynamic_array_ptr(&user_conn_array,
user_conn_array.elements - 1));
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,7 +563,6 @@ 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);
end_thread:
close_connection(net);
......@@ -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,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);
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,7 +2667,10 @@ 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
{
......
......@@ -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 ||
field->type() != FIELD_TYPE_BLOB)
{
if (field->key_type() != HA_KEYTYPE_TEXT ||
(!(ha_option & HA_KEY_READ_WRONG_STR) &&
!(keyinfo->flags & HA_FULLTEXT))))
!(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