Commit 410dd077 authored by unknown's avatar unknown

Remove warnings and portability fixes

New global read lock code
Fixed bug in DATETIME with WHERE optimization
Made UNION code more general.


include/global.h:
  Remove warning on Linux Alpha
include/mysql_com.h:
  Move some C variables inside extern "C" block.
include/mysqld_error.h:
  New error mesages
myisam/mi_write.c:
  cleanup
mysql-test/r/select.result:
  Fix because of table lists now always has a database argument.
mysql-test/r/type_datetime.result:
  Test for bug with datetime and where optimization
mysql-test/r/union.result:
  Updated result
mysql-test/t/type_datetime.test:
  New test for datetime
mysql-test/t/union.test:
  More testing of error conditions
sql/item_sum.cc:
  Remove warnings on Linux Alpha
sql/item_sum.h:
  Cleanup
sql/lock.cc:
  Cleaned up global lock handling
sql/log_event.cc:
  Removed default arguments from declarations (not allowed in cxx)
sql/mysql_priv.h:
  New prototypes
sql/mysqld.cc:
  Fix for global locks
sql/opt_range.cc:
  Cleanup
sql/share/czech/errmsg.txt:
  New errors
sql/share/danish/errmsg.txt:
  New errors
sql/share/dutch/errmsg.txt:
  New errors
sql/share/english/errmsg.txt:
  New errors
sql/share/estonian/errmsg.txt:
  New errors
sql/share/french/errmsg.txt:
  New errors
sql/share/german/errmsg.txt:
  New errors
sql/share/greek/errmsg.txt:
  New errors
sql/share/hungarian/errmsg.txt:
  New errors
sql/share/italian/errmsg.txt:
  New errors
sql/share/japanese/errmsg.txt:
  New errors
sql/share/korean/errmsg.txt:
  New errors
sql/share/norwegian-ny/errmsg.txt:
  New errors
sql/share/norwegian/errmsg.txt:
  New errors
sql/share/polish/errmsg.txt:
  New errors
sql/share/portuguese/errmsg.txt:
  New errors
sql/share/romanian/errmsg.txt:
  New errors
sql/share/russian/errmsg.txt:
  New errors
sql/share/slovak/errmsg.txt:
  New errors
sql/share/spanish/errmsg.txt:
  New errors
sql/share/swedish/errmsg.OLD:
  New errors
sql/share/swedish/errmsg.txt:
  New errors
sql/sql_acl.cc:
  Use thd->host_or_ip
sql/sql_class.cc:
  Use new global lock code
sql/sql_class.h:
  host_or_ip
sql/sql_db.cc:
  host_or_ip
sql/sql_delete.cc:
  Use now global lock code
sql/sql_lex.h:
  Cleanup of not used states and variables
sql/sql_parse.cc:
  Use now global locks.
  Made UNION code more general.
  Change to use thd->hosts_or_ip.
  TABLE_LIST now always has 'db' set.
sql/sql_repl.cc:
  Portability fixes.
  Changed wrong usage of my_vsnprintf -> my_snprintf
sql/sql_select.cc:
  Changes for UNION
sql/sql_show.cc:
  Cleanup
sql/sql_union.cc:
  Handle 'select_result' outside of mysql_union().
sql/sql_yacc.yy:
  Fixes for union
parent 97250b9c
...@@ -781,9 +781,9 @@ typedef union { ...@@ -781,9 +781,9 @@ typedef union {
*((uchar*) (T))= (uchar)(def_temp); \ *((uchar*) (T))= (uchar)(def_temp); \
*((uchar*) (T+1))=(uchar)((def_temp >> 8)); } *((uchar*) (T+1))=(uchar)((def_temp >> 8)); }
#define int3store(T,A) { /*lint -save -e734 */\ #define int3store(T,A) { /*lint -save -e734 */\
*((T))=(char) ((A));\ *((uchar*)(T))=(uchar) ((A));\
*((T)+1)=(char) (((A) >> 8));\ *((uchar*) (T)+1)=(uchar) (((A) >> 8));\
*((T)+2)=(char) (((A) >> 16)); \ *((uchar*)(T)+2)=(uchar) (((A) >> 16)); \
/*lint -restore */} /*lint -restore */}
#define int4store(T,A) { *(T)=(char) ((A));\ #define int4store(T,A) { *(T)=(char) ((A));\
*((T)+1)=(char) (((A) >> 8));\ *((T)+1)=(char) (((A) >> 8));\
......
...@@ -146,15 +146,15 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY, ...@@ -146,15 +146,15 @@ enum enum_field_types { FIELD_TYPE_DECIMAL, FIELD_TYPE_TINY,
#define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */ #define FIELD_TYPE_CHAR FIELD_TYPE_TINY /* For compability */
#define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */ #define FIELD_TYPE_INTERVAL FIELD_TYPE_ENUM /* For compability */
extern unsigned long max_allowed_packet;
extern unsigned long net_buffer_length;
#define net_new_transaction(net) ((net)->pkt_nr=0) #define net_new_transaction(net) ((net)->pkt_nr=0)
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern unsigned long max_allowed_packet;
extern unsigned long net_buffer_length;
int my_net_init(NET *net, Vio* vio); int my_net_init(NET *net, Vio* vio);
void net_end(NET *net); void net_end(NET *net);
void net_clear(NET *net); void net_clear(NET *net);
......
...@@ -217,4 +217,5 @@ ...@@ -217,4 +217,5 @@
#define ER_ERROR_WHEN_EXECUTING_COMMAND 1214 #define ER_ERROR_WHEN_EXECUTING_COMMAND 1214
#define ER_WRONG_USAGE 1215 #define ER_WRONG_USAGE 1215
#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1216 #define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1216
#define ER_ERROR_MESSAGES 217 #define ER_CANT_UPDATE_WITH_READLOCK 1217
#define ER_ERROR_MESSAGES 218
...@@ -35,7 +35,10 @@ static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key, ...@@ -35,7 +35,10 @@ static int _mi_balance_page(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,
static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page, static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
uchar *key, uint *return_key_length, uchar *key, uint *return_key_length,
uchar **after_key); uchar **after_key);
int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
uint key_length);
int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
uint key_length);
/* Write new record to database */ /* Write new record to database */
......
...@@ -1210,7 +1210,7 @@ fld1 fld1 ...@@ -1210,7 +1210,7 @@ fld1 fld1
companynr companyname companynr companyname
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 1199 t2 ALL NULL NULL NULL NULL 1199
t4 eq_ref PRIMARY PRIMARY 1 t2.companynr 1 where used; Not exists t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 where used; Not exists
table type possible_keys key key_len ref rows Extra table type possible_keys key key_len ref rows Extra
t4 ALL NULL NULL NULL NULL 12 t4 ALL NULL NULL NULL NULL 12
t2 ALL NULL NULL NULL NULL 1199 where used; Not exists t2 ALL NULL NULL NULL NULL 1199 where used; Not exists
......
...@@ -33,3 +33,5 @@ date_format(a,"%Y-%m-%d")=b right(a,6)=c+0 a=d+0 ...@@ -33,3 +33,5 @@ date_format(a,"%Y-%m-%d")=b right(a,6)=c+0 a=d+0
1 1 1 1 1 1
a a
0000-00-00 00:00:00 0000-00-00 00:00:00
id dt
1 2001-08-14 00:00:00
...@@ -56,5 +56,3 @@ t2 c 1 ...@@ -56,5 +56,3 @@ t2 c 1
t2 d 1 t2 d 1
t2 e 1 t2 e 1
t2 f 1 t2 f 1
table type possible_keys key key_len ref rows Extra
t2 ALL NULL NULL NULL NULL 4
...@@ -30,3 +30,12 @@ CREATE TABLE t1 (a datetime not null); ...@@ -30,3 +30,12 @@ CREATE TABLE t1 (a datetime not null);
insert into t1 values (0); insert into t1 values (0);
select * from t1 where a is null; select * from t1 where a is null;
drop table t1; drop table t1;
#
# Test with bug when propagating DATETIME to integer and WHERE optimization
#
create table t1 (id int, dt datetime);
insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00");
select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15');
drop table t1;
...@@ -16,17 +16,28 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select ...@@ -16,17 +16,28 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
select a,b from t1 union select a,b from t1; select a,b from t1 union select a,b from t1;
select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b; select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
# Test some error conditions with UNION
--error 1215
explain select a,b from t1 union all select a,b from t2; explain select a,b from t1 union all select a,b from t2;
# Test some error conditions with UNION
--error 1215 --error 1215
select a,b from t1 into outfile 'skr' union select a,b from t2; select a,b from t1 into outfile 'skr' union select a,b from t2;
--error 1215 --error 1215
select a,b from t1 order by a union select a,b from t2; select a,b from t1 order by a union select a,b from t2;
--error 1216
create table t3 select a,b from t1 union select a from t2;
--error 1215
insert into t3 select a from t1 order by a union select a from t2;
--error 1216 --error 1216
select a,b from t1 union select a from t2; select a,b from t1 union select a from t2;
# Test CREATE, INSERT and REPLACE
create table t3 select a,b from t1 union all select a,b from t2; create table t3 select a,b from t1 union all select a,b from t2;
insert into t3 select a,b from t1 union all select a,b from t2; insert into t3 select a,b from t1 union all select a,b from t2;
replace into t3 select a,b as c from t1 union all select a,b from t2;
drop table t1,t2,t3; drop table t1,t2,t3;
...@@ -790,12 +790,12 @@ String *Item_std_field::val_str(String *str) ...@@ -790,12 +790,12 @@ String *Item_std_field::val_str(String *str)
static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2) static int simple_raw_key_cmp(void* arg, byte* key1, byte* key2)
{ {
return memcmp(key1, key2, (int) arg); return memcmp(key1, key2, *(uint*) arg);
} }
static int simple_str_key_cmp(void* arg, byte* key1, byte* key2) static int simple_str_key_cmp(void* arg, byte* key1, byte* key2)
{ {
return my_sortcmp(key1, key2, (int) arg); return my_sortcmp(key1, key2, *(uint*) arg);
} }
/* /*
...@@ -904,7 +904,6 @@ bool Item_sum_count_distinct::setup(THD *thd) ...@@ -904,7 +904,6 @@ bool Item_sum_count_distinct::setup(THD *thd)
{ {
qsort_cmp2 compare_key; qsort_cmp2 compare_key;
void* cmp_arg; void* cmp_arg;
int key_len;
// to make things easier for dump_leaf if we ever have to dump to MyISAM // to make things easier for dump_leaf if we ever have to dump to MyISAM
restore_record(table,2); restore_record(table,2);
...@@ -937,7 +936,8 @@ bool Item_sum_count_distinct::setup(THD *thd) ...@@ -937,7 +936,8 @@ bool Item_sum_count_distinct::setup(THD *thd)
compare_key = (qsort_cmp2)simple_raw_key_cmp; compare_key = (qsort_cmp2)simple_raw_key_cmp;
break; break;
} }
cmp_arg = (void*)(key_len = field->pack_length()); key_length = field->pack_length();
cmp_arg = (void*) &key_length;
rec_offset = 1; rec_offset = 1;
} }
else // too bad, cannot cheat - there is more than one field else // too bad, cannot cheat - there is more than one field
...@@ -950,38 +950,38 @@ bool Item_sum_count_distinct::setup(THD *thd) ...@@ -950,38 +950,38 @@ bool Item_sum_count_distinct::setup(THD *thd)
(uint32*) thd->alloc(sizeof(uint32) * table->fields))) (uint32*) thd->alloc(sizeof(uint32) * table->fields)))
return 1; return 1;
for (key_len = 0, lengths=field_lengths; field < field_end; ++field) for (key_length = 0, lengths=field_lengths; field < field_end; ++field)
{ {
uint32 length= (*field)->pack_length(); uint32 length= (*field)->pack_length();
key_len += length; key_length += length;
*lengths++ = length; *lengths++ = length;
if (!(*field)->binary()) if (!(*field)->binary())
all_binary = 0; // Can't break loop here all_binary = 0; // Can't break loop here
} }
rec_offset = table->reclength - key_len; rec_offset = table->reclength - key_length;
if (all_binary) if (all_binary)
{ {
compare_key = (qsort_cmp2)simple_raw_key_cmp; compare_key = (qsort_cmp2)simple_raw_key_cmp;
cmp_arg = (void*)key_len; cmp_arg = (void*) &key_length;
} }
else else
{ {
compare_key = (qsort_cmp2) composite_key_cmp ; compare_key = (qsort_cmp2) composite_key_cmp ;
cmp_arg = (void*)this; cmp_arg = (void*) this;
} }
} }
init_tree(&tree, min(max_heap_table_size, sortbuff_size/16), 0, init_tree(&tree, min(max_heap_table_size, sortbuff_size/16), 0,
key_len, compare_key, 0, NULL, cmp_arg); key_length, compare_key, 0, NULL, cmp_arg);
use_tree = 1; use_tree = 1;
/* /*
The only time key_len could be 0 is if someone does The only time key_length could be 0 is if someone does
count(distinct) on a char(0) field - stupid thing to do, count(distinct) on a char(0) field - stupid thing to do,
but this has to be handled - otherwise someone can crash but this has to be handled - otherwise someone can crash
the server with a DoS attack the server with a DoS attack
*/ */
max_elements_in_tree = ((key_len) ? max_heap_table_size/key_len : max_elements_in_tree = ((key_length) ? max_heap_table_size/key_length :
1); 1);
} }
return 0; return 0;
......
...@@ -149,6 +149,7 @@ class Item_sum_count_distinct :public Item_sum_int ...@@ -149,6 +149,7 @@ class Item_sum_count_distinct :public Item_sum_int
uint32 *field_lengths; uint32 *field_lengths;
TMP_TABLE_PARAM *tmp_table_param; TMP_TABLE_PARAM *tmp_table_param;
TREE tree; TREE tree;
uint key_length;
// calculated based on max_heap_table_size. If reached, // calculated based on max_heap_table_size. If reached,
// walk the tree and dump it into MyISAM table // walk the tree and dump it into MyISAM table
......
...@@ -55,35 +55,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count) ...@@ -55,35 +55,13 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
Someone has issued LOCK ALL TABLES FOR READ and we want a write lock Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
Wait until the lock is gone Wait until the lock is gone
*/ */
if (thd->global_read_lock) // This thread had the read locks if (wait_if_global_read_lock(thd, 1))
{ {
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
write_lock_used->table_name);
my_free((gptr) sql_lock,MYF(0)); my_free((gptr) sql_lock,MYF(0));
sql_lock=0; sql_lock=0;
break; break;
} }
if (thd->version != refresh_version)
pthread_mutex_lock(&LOCK_open);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex);
while (global_read_lock && ! thd->killed &&
thd->version == refresh_version)
{
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
pthread_mutex_unlock(&LOCK_open);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
thd->proc_info= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);
if (thd->version != refresh_version || thd->killed)
{ {
my_free((gptr) sql_lock,MYF(0)); my_free((gptr) sql_lock,MYF(0));
goto retry; goto retry;
...@@ -502,3 +480,94 @@ static void print_lock_error(int error) ...@@ -502,3 +480,94 @@ static void print_lock_error(int error)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/****************************************************************************
Handling of global read locks
The global locks are handled through the global variables:
global_read_lock
waiting_for_read_lock
protect_against_global_read_lock
****************************************************************************/
volatile uint global_read_lock=0;
static volatile uint protect_against_global_read_lock=0;
static volatile uint waiting_for_read_lock=0;
bool lock_global_read_lock(THD *thd)
{
DBUG_ENTER("lock_global_read_lock");
if (!thd->global_read_lock)
{
(void) pthread_mutex_lock(&LOCK_open);
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
"Waiting to get readlock");
waiting_for_read_lock++;
while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open);
waiting_for_read_lock--;
if (thd->killed)
{
(void) pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(1);
}
thd->global_read_lock=1;
global_read_lock++;
(void) pthread_mutex_unlock(&LOCK_open);
}
DBUG_RETURN(0);
}
void unlock_global_read_lock(THD *thd)
{
uint tmp;
thd->global_read_lock=0;
pthread_mutex_lock(&LOCK_open);
tmp= --global_read_lock;
pthread_mutex_unlock(&LOCK_open);
/* Send the signal outside the mutex to avoid a context switch */
if (!tmp)
pthread_cond_broadcast(&COND_refresh);
}
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh)
{
const char *old_message;
bool result=0;
DBUG_ENTER("wait_if_global_read_lock");
(void) pthread_mutex_lock(&LOCK_open);
if (global_read_lock)
{
if (thd->global_read_lock) // This thread had the read locks
{
my_error(ER_CANT_UPDATE_WITH_READLOCK,MYF(0));
DBUG_RETURN(1);
}
old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
"Waiting for release of readlock");
while (global_read_lock && ! thd->killed &&
(!abort_on_refresh || thd->version == refresh_version))
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
if (thd->killed)
result=1;
thd->exit_cond(old_message);
}
if (!abort_on_refresh && !result)
protect_against_global_read_lock++;
pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(result);
}
void start_waiting_global_read_lock(THD *thd)
{
bool tmp;
(void) pthread_mutex_lock(&LOCK_open);
tmp= (!--protect_against_global_read_lock && waiting_for_read_lock);
(void) pthread_mutex_unlock(&LOCK_open);
if (tmp)
pthread_cond_broadcast(&COND_refresh);
}
...@@ -1054,8 +1054,7 @@ Slave_log_event::~Slave_log_event() ...@@ -1054,8 +1054,7 @@ Slave_log_event::~Slave_log_event()
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Slave_log_event::print(FILE* file, bool short_form = 0, void Slave_log_event::print(FILE* file, bool short_form, char* last_db)
char* last_db = 0)
{ {
char llbuff[22]; char llbuff[22];
if(short_form) if(short_form)
...@@ -1167,8 +1166,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len): ...@@ -1167,8 +1166,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len):
block_len = len - block_offset; block_len = len - block_offset;
} }
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Create_file_log_event::print(FILE* file, bool short_form = 0, void Create_file_log_event::print(FILE* file, bool short_form,
char* last_db = 0) char* last_db)
{ {
if (short_form) if (short_form)
return; return;
...@@ -1224,8 +1223,8 @@ int Append_block_log_event::write_data(IO_CACHE* file) ...@@ -1224,8 +1223,8 @@ int Append_block_log_event::write_data(IO_CACHE* file)
} }
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Append_block_log_event::print(FILE* file, bool short_form = 0, void Append_block_log_event::print(FILE* file, bool short_form,
char* last_db = 0) char* last_db)
{ {
if (short_form) if (short_form)
return; return;
...@@ -1273,8 +1272,8 @@ int Delete_file_log_event::write_data(IO_CACHE* file) ...@@ -1273,8 +1272,8 @@ int Delete_file_log_event::write_data(IO_CACHE* file)
} }
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Delete_file_log_event::print(FILE* file, bool short_form = 0, void Delete_file_log_event::print(FILE* file, bool short_form,
char* last_db = 0) char* last_db)
{ {
if (short_form) if (short_form)
return; return;
...@@ -1320,8 +1319,8 @@ int Execute_load_log_event::write_data(IO_CACHE* file) ...@@ -1320,8 +1319,8 @@ int Execute_load_log_event::write_data(IO_CACHE* file)
} }
#ifdef MYSQL_CLIENT #ifdef MYSQL_CLIENT
void Execute_load_log_event::print(FILE* file, bool short_form = 0, void Execute_load_log_event::print(FILE* file, bool short_form,
char* last_db = 0) char* last_db)
{ {
if (short_form) if (short_form)
return; return;
...@@ -1757,7 +1756,7 @@ int Execute_load_log_event::exec_event(struct st_master_info* mi) ...@@ -1757,7 +1756,7 @@ int Execute_load_log_event::exec_event(struct st_master_info* mi)
// can preserve ascending order of log sequence numbers - needed // can preserve ascending order of log sequence numbers - needed
// to handle failover // to handle failover
save_options = thd->options; save_options = thd->options;
thd->options &= ~OPTION_BIN_LOG; thd->options &= ~ (ulong) OPTION_BIN_LOG;
lev->thd = thd; lev->thd = thd;
if (lev->exec_event(0,0)) if (lev->exec_event(0,0))
{ {
......
...@@ -285,7 +285,6 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* table_list, ...@@ -285,7 +285,6 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
HA_CHECK_OPT* check_opt); HA_CHECK_OPT* check_opt);
/* net_pkg.c */ /* net_pkg.c */
void send_error(NET *net,uint sql_errno=0, const char *err=0);
void send_warning(NET *net, uint sql_errno, const char *err=0); void send_warning(NET *net, uint sql_errno, const char *err=0);
void net_printf(NET *net,uint sql_errno, ...); void net_printf(NET *net,uint sql_errno, ...);
void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L, void send_ok(NET *net,ha_rows affected_rows=0L,ulonglong id=0L,
...@@ -312,11 +311,12 @@ SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length); ...@@ -312,11 +311,12 @@ SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields, int setup_order(THD *thd,TABLE_LIST *tables, List<Item> &fields,
List <Item> &all_fields, ORDER *order); List <Item> &all_fields, ORDER *order);
int handle_select(THD *thd, LEX *lex, select_result *result);
int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds, int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds,
List<Item_func_match> &ftfuncs, List<Item_func_match> &ftfuncs,
ORDER *order, ORDER *group,Item *having,ORDER *proc_param, ORDER *order, ORDER *group,Item *having,ORDER *proc_param,
ulong select_type,select_result *result); ulong select_type,select_result *result);
int mysql_union(THD *thd,LEX *lex,select_result *create_insert=(select_result *)NULL); int mysql_union(THD *thd,LEX *lex,select_result *result);
Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, Field *create_tmp_field(TABLE *table,Item *item, Item::Type type,
Item_result_field ***copy_func, Field **from_field, Item_result_field ***copy_func, Field **from_field,
bool group,bool modify_item); bool group,bool modify_item);
...@@ -586,6 +586,10 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count); ...@@ -586,6 +586,10 @@ void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table);
void mysql_lock_abort(THD *thd, TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table);
MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b);
bool lock_global_read_lock(THD *thd);
void unlock_global_read_lock(THD *thd);
bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh);
void start_waiting_global_read_lock(THD *thd);
/* Lock based on name */ /* Lock based on name */
int lock_table_name(THD *thd, TABLE_LIST *table_list); int lock_table_name(THD *thd, TABLE_LIST *table_list);
......
...@@ -262,7 +262,7 @@ bool server_id_supplied = 0; ...@@ -262,7 +262,7 @@ bool server_id_supplied = 0;
uint mysql_port; uint mysql_port;
uint test_flags = 0, select_errors=0, dropping_tables=0,ha_open_options=0; uint test_flags = 0, select_errors=0, dropping_tables=0,ha_open_options=0;
uint volatile thread_count=0, thread_running=0, kill_cached_threads=0, uint volatile thread_count=0, thread_running=0, kill_cached_threads=0,
wake_thread=0, global_read_lock=0; wake_thread=0;
ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL | ulong thd_startup_options=(OPTION_UPDATE_LOG | OPTION_AUTO_IS_NULL |
OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE ); OPTION_BIN_LOG | OPTION_QUOTE_SHOW_CREATE );
uint protocol_version=PROTOCOL_VERSION; uint protocol_version=PROTOCOL_VERSION;
......
...@@ -2637,7 +2637,6 @@ int QUICK_SELECT_DESC::get_next() ...@@ -2637,7 +2637,6 @@ int QUICK_SELECT_DESC::get_next()
} }
range = 0; // To next range range = 0; // To next range
} }
DBUG_RETURN(HA_ERR_END_OF_FILE);
} }
/* /*
......
...@@ -227,3 +227,4 @@ ...@@ -227,3 +227,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -221,3 +221,4 @@ ...@@ -221,3 +221,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -222,3 +222,4 @@ ...@@ -222,3 +222,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -222,3 +222,4 @@ ...@@ -222,3 +222,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -221,3 +221,4 @@ ...@@ -221,3 +221,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -220,3 +220,4 @@ ...@@ -220,3 +220,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -220,3 +220,4 @@ ...@@ -220,3 +220,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -220,3 +220,4 @@ ...@@ -220,3 +220,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -220,3 +220,4 @@ ...@@ -220,3 +220,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -222,3 +222,4 @@ ...@@ -222,3 +222,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -222,3 +222,4 @@ ...@@ -222,3 +222,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -221,3 +221,4 @@ ...@@ -221,3 +221,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -226,3 +226,4 @@ ...@@ -226,3 +226,4 @@
"Error when executing command %s: %-.128s", "Error when executing command %s: %-.128s",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -219,3 +219,4 @@ ...@@ -219,3 +219,4 @@
"Error de %s: %-128%", "Error de %s: %-128%",
"Wrong usage of %s and %s", "Wrong usage of %s and %s",
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock",
...@@ -205,9 +205,17 @@ ...@@ -205,9 +205,17 @@
"Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'", "Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'",
"Kunde inte starta en tråd för replikering", "Kunde inte starta en tråd för replikering",
"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar", "Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar",
"Du kan endast använda konstant-uttryck med SET", "Man kan endast använda konstant-uttryck med SET",
"Tiden att få ett lås var för lång", "Fick inte ett lås i tid",
"Antal lås är större än vad som ryms i lock tabellen", "Antal lås överskrider antalet reserverade lås",
"Du kan inte låsa tabeller/poster under READ UNCOMMITTED", "Updaterings-lås kan inte göras när man använder READ UNCOMMITTED",
"Fick fel vid inloggning till master: %-.128s", "DROP DATABASE är inte tillåtet när man har ett globalt läs-lås",
"Fick fel vid exekvering av fråga på master: %-.128s", "CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås",
"Felaktiga argument till %s",
"%-.32s@%-.64s har inte rättigheter att skapa nya användare",
"Fick fel vid anslutning till master: %-.128s",
"Fick fel vid utförande av command på mastern: %-.128s",
"Fick fel vid utförande av %s: %-.128s",
"Felaktig använding av %s and %s",
"SELECT kommandona har olika antal kolumner"
"Kan inte utföra kommandot emedan du har ett READ lås",
...@@ -218,3 +218,4 @@ ...@@ -218,3 +218,4 @@
"Fick fel vid utförande av %s: %-.128s", "Fick fel vid utförande av %s: %-.128s",
"Felaktig använding av %s and %s", "Felaktig använding av %s and %s",
"SELECT kommandona har olika antal kolumner" "SELECT kommandona har olika antal kolumner"
"Kan inte utföra kommandot emedan du har ett READ lås",
...@@ -1006,7 +1006,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo, ...@@ -1006,7 +1006,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER, my_printf_error(ER_NO_PERMISSION_TO_CREATE_USER,
ER(ER_NO_PERMISSION_TO_CREATE_USER), ER(ER_NO_PERMISSION_TO_CREATE_USER),
MYF(0),thd->user, MYF(0),thd->user,
thd->host ? thd->host : thd->ip ? thd->ip: ""); thd->host_or_ip);
error= -1; error= -1;
goto end; goto end;
} }
...@@ -1503,8 +1503,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, ...@@ -1503,8 +1503,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
uint store_table_rights,store_col_rights; uint store_table_rights,store_col_rights;
DBUG_ENTER("replace_table_table"); DBUG_ENTER("replace_table_table");
strxmov(grantor,thd->user,"@",thd->host ? thd->host : thd->ip ? thd->ip :"", strxmov(grantor, thd->user, "@", thd->host_or_ip, NullS);
NullS);
// The following should always succeed as new users are created before // The following should always succeed as new users are created before
// this function is called! // this function is called!
...@@ -2091,7 +2090,7 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables, ...@@ -2091,7 +2090,7 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR, net_printf(&thd->net,ER_TABLEACCESS_DENIED_ERROR,
command, command,
thd->priv_user, thd->priv_user,
thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"), thd->host_or_ip,
table ? table->real_name : "unknown"); table ? table->real_name : "unknown");
} }
return 1; return 1;
...@@ -2154,7 +2153,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name, ...@@ -2154,7 +2153,7 @@ bool check_grant_column (THD *thd,TABLE *table, const char *name,
MYF(0), MYF(0),
command, command,
thd->priv_user, thd->priv_user,
thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"), thd->host_or_ip,
name, name,
table ? table->real_name : "unknown"); table ? table->real_name : "unknown");
} }
...@@ -2212,7 +2211,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table) ...@@ -2212,7 +2211,7 @@ bool check_grant_all_columns(THD *thd,uint want_access, TABLE *table)
MYF(0), MYF(0),
command, command,
thd->priv_user, thd->priv_user,
thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"), thd->host_or_ip,
field ? field->field_name : "unknown", field ? field->field_name : "unknown",
table->real_name); table->real_name);
return 1; return 1;
......
...@@ -82,6 +82,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), ...@@ -82,6 +82,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
global_read_lock(0),bootstrap(0) global_read_lock(0),bootstrap(0)
{ {
host=user=priv_user=db=query=ip=0; host=user=priv_user=db=query=ip=0;
host_or_ip="unknown ip";
locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password= locked=killed=count_cuted_fields=some_tables_deleted=no_errors=password=
query_start_used=0; query_start_used=0;
query_length=col_access=0; query_length=col_access=0;
...@@ -183,12 +184,7 @@ THD::~THD() ...@@ -183,12 +184,7 @@ THD::~THD()
} }
#endif #endif
if (global_read_lock) if (global_read_lock)
{ unlock_global_read_lock(this);
pthread_mutex_lock(&LOCK_open);
::global_read_lock--;
pthread_cond_broadcast(&COND_refresh);
pthread_mutex_unlock(&LOCK_open);
}
if (ull) if (ull)
{ {
pthread_mutex_lock(&LOCK_user_locks); pthread_mutex_lock(&LOCK_user_locks);
......
...@@ -239,7 +239,7 @@ public: ...@@ -239,7 +239,7 @@ public:
struct rand_struct rand; struct rand_struct rand;
char *query,*thread_stack; char *query,*thread_stack;
char *host,*user,*priv_user,*db,*ip; char *host,*user,*priv_user,*db,*ip;
const char *proc_info; const char *proc_info, *host_or_ip;
uint client_capabilities,sql_mode,max_packet_length; uint client_capabilities,sql_mode,max_packet_length;
uint master_access,db_access; uint master_access,db_access;
TABLE *open_tables,*temporary_tables, *handler_tables; TABLE *open_tables,*temporary_tables, *handler_tables;
......
...@@ -348,11 +348,11 @@ bool mysql_change_db(THD *thd,const char *name) ...@@ -348,11 +348,11 @@ bool mysql_change_db(THD *thd,const char *name)
{ {
net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
thd->priv_user, thd->priv_user,
thd->host ? thd->host : thd->ip ? thd->ip : "unknown", thd->host_or_ip,
dbname); dbname);
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR), mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
thd->priv_user, thd->priv_user,
thd->host ? thd->host : thd->ip ? thd->ip : "unknown", thd->host_or_ip,
dbname); dbname);
my_free(dbname,MYF(0)); my_free(dbname,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
......
...@@ -35,26 +35,10 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) ...@@ -35,26 +35,10 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table)
TABLE **table_ptr; TABLE **table_ptr;
DBUG_ENTER("generate_table"); DBUG_ENTER("generate_table");
if (wait_if_global_read_lock(thd,0))
DBUG_RETURN(1);
thd->proc_info="generate_table"; thd->proc_info="generate_table";
if (global_read_lock)
{
if(thd->global_read_lock)
{
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
table_list->real_name);
DBUG_RETURN(-1);
}
pthread_mutex_lock(&LOCK_open);
while (global_read_lock && ! thd->killed ||
thd->version != refresh_version)
{
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
pthread_mutex_unlock(&LOCK_open);
}
/* If it is a temporary table, close and regenerate it */ /* If it is a temporary table, close and regenerate it */
if ((table_ptr=find_temporary_table(thd,table_list->db, if ((table_ptr=find_temporary_table(thd,table_list->db,
table_list->real_name))) table_list->real_name)))
...@@ -91,6 +75,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) ...@@ -91,6 +75,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table)
if (!locked_table) if (!locked_table)
{ {
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
start_waiting_global_read_lock(thd);
DBUG_RETURN(1); // We must get a lock on table DBUG_RETURN(1); // We must get a lock on table
} }
} }
...@@ -118,6 +103,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) ...@@ -118,6 +103,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table)
} }
send_ok(&thd->net); // This should return record count send_ok(&thd->net); // This should return record count
} }
start_waiting_global_read_lock(thd);
DBUG_RETURN(error ? -1 : 0); DBUG_RETURN(error ? -1 : 0);
} }
...@@ -298,7 +284,7 @@ int mysql_delete(THD *thd, ...@@ -298,7 +284,7 @@ int mysql_delete(THD *thd,
int refposcmp2(void* arg, const void *a,const void *b) int refposcmp2(void* arg, const void *a,const void *b)
{ {
return memcmp(a,b,(int) arg); return memcmp(a,b, *(int*) arg);
} }
multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
...@@ -321,7 +307,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, ...@@ -321,7 +307,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK); (void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
(void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD); (void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD);
tempfiles[counter] = new Unique (refposcmp2, tempfiles[counter] = new Unique (refposcmp2,
(void *) table->file->ref_length, (void *) &table->file->ref_length,
table->file->ref_length, table->file->ref_length,
MEM_STRIP_BUF_SIZE); MEM_STRIP_BUF_SIZE);
} }
......
...@@ -55,8 +55,8 @@ enum enum_sql_command { ...@@ -55,8 +55,8 @@ enum enum_sql_command {
SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS, SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS,
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA, SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, SQLCOM_UNION_SELECT, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE,
SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_NONE SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER,
}; };
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
...@@ -106,7 +106,6 @@ enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE}; ...@@ -106,7 +106,6 @@ enum sub_select_type {UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE};
typedef struct st_select_lex { typedef struct st_select_lex {
enum sub_select_type linkage; enum sub_select_type linkage;
uint select_number; /* For Item_select */
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */ char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
Item *where,*having; Item *where,*having;
ha_rows select_limit,offset_limit; ha_rows select_limit,offset_limit;
......
This diff is collapsed.
...@@ -84,7 +84,9 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, ...@@ -84,7 +84,9 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name,
int2store(header + FLAGS_OFFSET, 0); int2store(header + FLAGS_OFFSET, 0);
int4store(header + LOG_SEQ_OFFSET, 0); int4store(header + LOG_SEQ_OFFSET, 0);
packet->append(header, sizeof(header)); packet->append(header, sizeof(header));
int8store(buf, 4); // tell slave to skip magic number /* We need to split the next statement because of problem with cxx */
int4store(buf,4); // tell slave to skip magic number
int4store(buf+4,0);
packet->append(buf, ROTATE_HEADER_LEN); packet->append(buf, ROTATE_HEADER_LEN);
packet->append(p,ident_len); packet->append(p,ident_len);
if (my_net_write(net, (char*)packet->ptr(), packet->length())) if (my_net_write(net, (char*)packet->ptr(), packet->length()))
...@@ -1041,7 +1043,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, ...@@ -1041,7 +1043,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
Log_event* ev; Log_event* ev;
if (!(ev = Log_event::read_log_event(log, 0))) if (!(ev = Log_event::read_log_event(log, 0)))
{ {
my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE, my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
"Error reading start event in log '%s'", "Error reading start event in log '%s'",
(char*)log_file_name); (char*)log_file_name);
return 0; return 0;
...@@ -1050,7 +1052,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, ...@@ -1050,7 +1052,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
if (!(ev = Log_event::read_log_event(log, 0))) if (!(ev = Log_event::read_log_event(log, 0)))
{ {
my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE, my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
"Error reading slave event in log '%s'", "Error reading slave event in log '%s'",
(char*)log_file_name); (char*)log_file_name);
return 0; return 0;
...@@ -1058,7 +1060,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, ...@@ -1058,7 +1060,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
if (ev->get_type_code() != SLAVE_EVENT) if (ev->get_type_code() != SLAVE_EVENT)
{ {
my_vsnprintf(errmsg, SLAVE_ERRMSG_SIZE, my_snprintf(errmsg, SLAVE_ERRMSG_SIZE,
"Second event in log '%s' is not slave event", "Second event in log '%s' is not slave event",
(char*)log_file_name); (char*)log_file_name);
delete ev; delete ev;
......
...@@ -143,6 +143,34 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -143,6 +143,34 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct); bool distinct);
static void describe_info(THD *thd, const char *info); static void describe_info(THD *thd, const char *info);
/*
This handles SELECT with and without UNION
*/
int handle_select(THD *thd, LEX *lex, select_result *result)
{
int res;
register SELECT_LEX *select_lex = &lex->select_lex;
if (select_lex->next)
res=mysql_union(thd,lex,result);
else
res=mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first,
select_lex->item_list,
select_lex->where,
select_lex->ftfunc_list,
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) lex->proc_list.first,
select_lex->options | thd->options,
result);
if (res && result)
result->abort();
delete result;
return res;
}
/***************************************************************************** /*****************************************************************************
** check fields, find best join, do the select and output fields. ** check fields, find best join, do the select and output fields.
** mysql_select assumes that all tables are allready opened ** mysql_select assumes that all tables are allready opened
...@@ -2985,7 +3013,9 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level, ...@@ -2985,7 +3013,9 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_level,
Item_func_eq *func=(Item_func_eq*) cond; Item_func_eq *func=(Item_func_eq*) cond;
bool left_const= func->arguments()[0]->const_item(); bool left_const= func->arguments()[0]->const_item();
bool right_const=func->arguments()[1]->const_item(); bool right_const=func->arguments()[1]->const_item();
if (!(left_const && right_const)) if (!(left_const && right_const) &&
(func->arguments()[0]->result_type() ==
(func->arguments()[1]->result_type())))
{ {
if (right_const) if (right_const)
{ {
......
...@@ -993,10 +993,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) ...@@ -993,10 +993,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thread_info *thd_info=new thread_info; thread_info *thd_info=new thread_info;
thd_info->thread_id=tmp->thread_id; thd_info->thread_id=tmp->thread_id;
thd_info->user=thd->strdup(tmp->user ? tmp->user : (tmp->system_thread ? thd_info->user=thd->strdup(tmp->user ? tmp->user :
(tmp->system_thread ?
"system user" : "unauthenticated user")); "system user" : "unauthenticated user"));
thd_info->host=thd->strdup(tmp->host ? tmp->host : (tmp->ip ? tmp->ip : thd_info->host=thd->strdup(tmp->host ? tmp->host :
(tmp->system_thread ? "none" : "connecting host"))); (tmp->ip ? tmp->ip :
(tmp->system_thread ? "none" :
"connecting host")));
if ((thd_info->db=tmp->db)) // Safe test if ((thd_info->db=tmp->db)) // Safe test
thd_info->db=thd->strdup(thd_info->db); thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command; thd_info->command=(int) tmp->command;
......
...@@ -25,21 +25,34 @@ ...@@ -25,21 +25,34 @@
#include "sql_select.h" #include "sql_select.h"
int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *)NULL) int mysql_union(THD *thd, LEX *lex,select_result *result)
{ {
SELECT_LEX *sl, *last_sl; SELECT_LEX *sl, *last_sl;
ORDER *order; ORDER *order;
List<Item> item_list; List<Item> item_list;
/* TABLE_LIST *s=(TABLE_LIST*) lex->select_lex.table_list.first; */
TABLE *table; TABLE *table;
TABLE_LIST *first_table, result_table_list; TABLE_LIST *first_table, result_table_list;
TMP_TABLE_PARAM tmp_table_param; TMP_TABLE_PARAM tmp_table_param;
select_result *result;
select_union *union_result; select_union *union_result;
int res; int res;
uint elements; uint elements;
DBUG_ENTER("mysql_union"); DBUG_ENTER("mysql_union");
if (lex->select_lex.options & SELECT_DESCRIBE)
{
my_error(ER_WRONG_USAGE,MYF(0),"DESCRIBE","UNION");
return -1;
}
/* Fix tables--to-be-unioned-from list to point at opened tables */
for (sl=&lex->select_lex; sl; sl=sl->next)
{
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor;
cursor=cursor->next)
cursor->table= ((TABLE_LIST*) cursor->table)->table;
}
/* Find last select part as it's here ORDER BY and GROUP BY is stored */ /* Find last select part as it's here ORDER BY and GROUP BY is stored */
elements= lex->select_lex.item_list.elements; elements= lex->select_lex.item_list.elements;
for (last_sl= &lex->select_lex; for (last_sl= &lex->select_lex;
...@@ -60,7 +73,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result * ...@@ -60,7 +73,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *
/* Create a list of items that will be in the result set */ /* Create a list of items that will be in the result set */
first_table= (TABLE_LIST*) lex->select_lex.table_list.first; first_table= (TABLE_LIST*) lex->select_lex.table_list.first;
if (create_insert) first_table=first_table->next;
while ((item= it++)) while ((item= it++))
if (item_list.push_back(item)) if (item_list.push_back(item))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -96,8 +108,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result * ...@@ -96,8 +108,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *
if (thd->select_limit == HA_POS_ERROR) if (thd->select_limit == HA_POS_ERROR)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
res=mysql_select(thd,(sl == &lex->select_lex) ? first_table : res=mysql_select(thd, (TABLE_LIST*) sl->table_list.first,
(TABLE_LIST*) sl->table_list.first,
sl->item_list, sl->item_list,
sl->where, sl->where,
sl->ftfunc_list, sl->ftfunc_list,
...@@ -116,19 +127,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result * ...@@ -116,19 +127,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *
goto exit; goto exit;
} }
delete union_result; delete union_result;
if (create_insert)
result=create_insert; /* Send result to 'result' */
else if (lex->exchange)
{
if (lex->exchange->dumpfile)
result=new select_dump(lex->exchange);
else
result=new select_export(lex->exchange);
}
else
result=new select_send();
res =-1; res =-1;
if (result)
{ {
/* Create a list of fields in the temporary table */ /* Create a list of fields in the temporary table */
List_iterator<Item> it(item_list); List_iterator<Item> it(item_list);
...@@ -146,9 +147,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result * ...@@ -146,9 +147,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *create_insert=(select_result *
item_list, NULL, ftfunc_list, order, item_list, NULL, ftfunc_list, order,
(ORDER*) NULL, NULL, (ORDER*) NULL, (ORDER*) NULL, NULL, (ORDER*) NULL,
thd->options, result); thd->options, result);
if (res)
result->abort();
delete result;
} }
exit: exit:
......
...@@ -1317,9 +1317,14 @@ table_to_table: ...@@ -1317,9 +1317,14 @@ table_to_table:
select: select:
SELECT_SYM SELECT_SYM
{
Lex->sql_command= SQLCOM_SELECT;
}
select_part2;
select_part2:
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->sql_command == SQLCOM_NONE) lex->sql_command= SQLCOM_SELECT;
lex->lock_option=TL_READ; lex->lock_option=TL_READ;
mysql_init_select(lex); mysql_init_select(lex);
} }
...@@ -2504,7 +2509,7 @@ describe: ...@@ -2504,7 +2509,7 @@ describe:
YYABORT; YYABORT;
} }
opt_describe_column opt_describe_column
| describe_command select { Select->options|= SELECT_DESCRIBE }; | describe_command select { Lex->select_lex.options|= SELECT_DESCRIBE };
describe_command: describe_command:
...@@ -3416,13 +3421,7 @@ union_list: ...@@ -3416,13 +3421,7 @@ union_list:
mysql_new_select(lex); mysql_new_select(lex);
lex->select->linkage=UNION_TYPE; lex->select->linkage=UNION_TYPE;
} }
select SELECT_SYM select_part2
{
LEX *lex=Lex;
if (lex->sql_command == SQLCOM_SELECT)
lex->sql_command=SQLCOM_UNION_SELECT;
}
union_option: union_option:
/* empty */ {} /* empty */ {}
......
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