mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 15:24:16 +01:00
Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
This commit is contained in:
commit
68c2afa8a5
50 changed files with 541 additions and 547 deletions
|
@ -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,
|
||||||
#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 @@
|
||||||
#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,
|
||||||
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 */
|
||||||
|
|
||||||
|
@ -214,7 +217,7 @@ int _mi_ck_write(MI_INFO *info, uint keynr, uchar *key, uint key_length)
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
|
int _mi_ck_write_btree(register MI_INFO *info, uint keynr, uchar *key,
|
||||||
uint key_length)
|
uint key_length)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("_mi_ck_write_btree");
|
DBUG_ENTER("_mi_ck_write_btree");
|
||||||
|
@ -710,7 +713,7 @@ typedef struct {
|
||||||
} bulk_insert_param;
|
} bulk_insert_param;
|
||||||
|
|
||||||
int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
|
int _mi_ck_write_tree(register MI_INFO *info, uint keynr, uchar *key,
|
||||||
uint key_length)
|
uint key_length)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
DBUG_ENTER("_mi_ck_write_tree");
|
DBUG_ENTER("_mi_ck_write_tree");
|
||||||
|
|
|
@ -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
|
||||||
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
|
||||||
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);
|
||||||
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
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
(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
|
||||||
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
|
||||||
|
@ -169,7 +170,7 @@ class Item_sum_count_distinct :public Item_sum_int
|
||||||
|
|
||||||
friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
|
friend int composite_key_cmp(void* arg, byte* key1, byte* key2);
|
||||||
friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
friend int dump_leaf(byte* key, uint32 count __attribute__((unused)),
|
||||||
Item_sum_count_distinct* item);
|
Item_sum_count_distinct* item);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Item_sum_count_distinct(List<Item> &list)
|
Item_sum_count_distinct(List<Item> &list)
|
||||||
|
|
117
sql/lock.cc
117
sql/lock.cc
|
@ -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)
|
||||||
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()
|
||||||
|
|
||||||
#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):
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
#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)
|
||||||
// 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,
|
||||||
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);
|
||||||
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);
|
||||||
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;
|
||||||
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()
|
||||||
}
|
}
|
||||||
range = 0; // To next range
|
range = 0; // To next range
|
||||||
}
|
}
|
||||||
DBUG_RETURN(HA_ERR_END_OF_FILE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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 @@
|
||||||
"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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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),
|
||||||
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()
|
||||||
}
|
}
|
||||||
#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:
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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,
|
||||||
|
|
||||||
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,
|
||||||
(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 {
|
||||||
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};
|
||||||
|
|
||||||
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;
|
||||||
|
|
637
sql/sql_parse.cc
637
sql/sql_parse.cc
|
@ -47,8 +47,7 @@ static void mysql_init_query(THD *thd);
|
||||||
static void remove_escape(char *name);
|
static void remove_escape(char *name);
|
||||||
static void refresh_status(void);
|
static void refresh_status(void);
|
||||||
static bool append_file_to_dir(char **filename_ptr, char *table_name);
|
static bool append_file_to_dir(char **filename_ptr, char *table_name);
|
||||||
static int create_total_list_and_check_acl(THD *thd, LEX *lex,
|
static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result);
|
||||||
TABLE_LIST **result, bool skip_first = false);
|
|
||||||
static int handle_create_select(THD *thd, LEX *lex, select_result *c_i);
|
static int handle_create_select(THD *thd, LEX *lex, select_result *c_i);
|
||||||
|
|
||||||
const char *any_db="*any*"; // Special symbol for check_access
|
const char *any_db="*any*"; // Special symbol for check_access
|
||||||
|
@ -120,18 +119,18 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||||
DBUG_PRINT("general",
|
DBUG_PRINT("general",
|
||||||
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
|
("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'",
|
||||||
thd->client_capabilities, thd->max_packet_length,
|
thd->client_capabilities, thd->max_packet_length,
|
||||||
thd->host ? thd->host : thd->ip, thd->priv_user,
|
thd->host_or_ip, thd->priv_user,
|
||||||
passwd[0] ? "yes": "no",
|
passwd[0] ? "yes": "no",
|
||||||
thd->master_access, thd->db ? thd->db : "*none*"));
|
thd->master_access, thd->db ? thd->db : "*none*"));
|
||||||
if (thd->master_access & NO_ACCESS)
|
if (thd->master_access & NO_ACCESS)
|
||||||
{
|
{
|
||||||
net_printf(net, ER_ACCESS_DENIED_ERROR,
|
net_printf(net, ER_ACCESS_DENIED_ERROR,
|
||||||
thd->user,
|
thd->user,
|
||||||
thd->host ? thd->host : thd->ip,
|
thd->host_or_ip,
|
||||||
passwd[0] ? ER(ER_YES) : ER(ER_NO));
|
passwd[0] ? ER(ER_YES) : ER(ER_NO));
|
||||||
mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
|
mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
|
||||||
thd->user,
|
thd->user,
|
||||||
thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
|
thd->host_or_ip,
|
||||||
passwd[0] ? ER(ER_YES) : ER(ER_NO));
|
passwd[0] ? ER(ER_YES) : ER(ER_NO));
|
||||||
return(1); // Error already given
|
return(1); // Error already given
|
||||||
}
|
}
|
||||||
|
@ -152,7 +151,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||||
(char*) "%s@%s on %s" :
|
(char*) "%s@%s on %s" :
|
||||||
(char*) "%s@%s as anonymous on %s"),
|
(char*) "%s@%s as anonymous on %s"),
|
||||||
user,
|
user,
|
||||||
thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
|
thd->host_or_ip,
|
||||||
db ? db : (char*) "");
|
db ? db : (char*) "");
|
||||||
thd->db_access=0;
|
thd->db_access=0;
|
||||||
if (max_user_connections &&
|
if (max_user_connections &&
|
||||||
|
@ -331,6 +330,7 @@ check_connections(THD *thd)
|
||||||
return (ER_BAD_HOST_ERROR);
|
return (ER_BAD_HOST_ERROR);
|
||||||
if (!(thd->ip = my_strdup(ip,MYF(0))))
|
if (!(thd->ip = my_strdup(ip,MYF(0))))
|
||||||
return (ER_OUT_OF_RESOURCES);
|
return (ER_OUT_OF_RESOURCES);
|
||||||
|
thd->host_or_ip=thd->ip;
|
||||||
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
|
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
|
||||||
/* Fast local hostname resolve for Win32 */
|
/* Fast local hostname resolve for Win32 */
|
||||||
if (!strcmp(thd->ip,"127.0.0.1"))
|
if (!strcmp(thd->ip,"127.0.0.1"))
|
||||||
|
@ -353,6 +353,7 @@ check_connections(THD *thd)
|
||||||
else /* Hostname given means that the connection was on a socket */
|
else /* Hostname given means that the connection was on a socket */
|
||||||
{
|
{
|
||||||
DBUG_PRINT("general",("Host: %s",thd->host));
|
DBUG_PRINT("general",("Host: %s",thd->host));
|
||||||
|
thd->host_or_ip=thd->host;
|
||||||
thd->ip=0;
|
thd->ip=0;
|
||||||
bzero((char*) &thd->remote,sizeof(struct sockaddr));
|
bzero((char*) &thd->remote,sizeof(struct sockaddr));
|
||||||
}
|
}
|
||||||
|
@ -531,7 +532,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
||||||
if ((error=check_connections(thd)))
|
if ((error=check_connections(thd)))
|
||||||
{ // Wrong permissions
|
{ // Wrong permissions
|
||||||
if (error > 0)
|
if (error > 0)
|
||||||
net_printf(net,error,thd->host ? thd->host : thd->ip);
|
net_printf(net,error,thd->host_or_ip);
|
||||||
#ifdef __NT__
|
#ifdef __NT__
|
||||||
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
|
if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
|
||||||
sleep(1); /* must wait after eof() */
|
sleep(1); /* must wait after eof() */
|
||||||
|
@ -562,7 +563,7 @@ pthread_handler_decl(handle_one_connection,arg)
|
||||||
sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
|
sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
|
||||||
thd->thread_id,(thd->db ? thd->db : "unconnected"),
|
thd->thread_id,(thd->db ? thd->db : "unconnected"),
|
||||||
thd->user ? thd->user : "unauthenticated",
|
thd->user ? thd->user : "unauthenticated",
|
||||||
(thd->host ? thd->host : thd->ip ? thd->ip : "unknown"),
|
thd->host_or_ip,
|
||||||
(net->last_errno ? ER(net->last_errno) :
|
(net->last_errno ? ER(net->last_errno) :
|
||||||
ER(ER_UNKNOWN_ERROR)));
|
ER(ER_UNKNOWN_ERROR)));
|
||||||
send_error(net,net->last_errno,NullS);
|
send_error(net,net->last_errno,NullS);
|
||||||
|
@ -694,9 +695,8 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
net_flush(&thd->net);
|
net_flush(&thd->net);
|
||||||
error = table->file->dump(thd,fd);
|
if ((error = table->file->dump(thd,fd)))
|
||||||
if(error)
|
my_error(ER_GET_ERRNO, MYF(0));
|
||||||
my_error(ER_GET_ERRNO, MYF(0));
|
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||||
thread_running++;
|
thread_running++;
|
||||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||||
thd->set_time();
|
thd->set_time();
|
||||||
thd->lex.select_lex.options=0; // We store status here
|
thd->lex.select_lex.options=0; // We store status here
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case COM_INIT_DB:
|
case COM_INIT_DB:
|
||||||
if (!mysql_change_db(thd,packet))
|
if (!mysql_change_db(thd,packet))
|
||||||
|
@ -1073,10 +1073,13 @@ mysql_execute_command(void)
|
||||||
SELECT_LEX *select_lex = lex->select;
|
SELECT_LEX *select_lex = lex->select;
|
||||||
DBUG_ENTER("mysql_execute_command");
|
DBUG_ENTER("mysql_execute_command");
|
||||||
|
|
||||||
if(table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables))
|
/*
|
||||||
DBUG_VOID_RETURN; // skip if we are in the slave thread, some table
|
Skip if we are in the slave thread, some table rules have been given
|
||||||
// rules have been given and the table list says the query should not be
|
and the table list says the query should not be replicated
|
||||||
// replicated
|
TODO: UPDATE this for UNION
|
||||||
|
*/
|
||||||
|
if (table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables))
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
switch (lex->sql_command) {
|
switch (lex->sql_command) {
|
||||||
case SQLCOM_SELECT:
|
case SQLCOM_SELECT:
|
||||||
|
@ -1084,6 +1087,9 @@ mysql_execute_command(void)
|
||||||
select_result *result;
|
select_result *result;
|
||||||
if (select_lex->options & SELECT_DESCRIBE)
|
if (select_lex->options & SELECT_DESCRIBE)
|
||||||
lex->exchange=0;
|
lex->exchange=0;
|
||||||
|
/* Save a call, as it's very uncomon that we use unions */
|
||||||
|
if (lex->select_lex.next && (res = create_total_list(thd,lex,&tables)))
|
||||||
|
break;
|
||||||
if (tables)
|
if (tables)
|
||||||
{
|
{
|
||||||
res=check_table_access(thd,
|
res=check_table_access(thd,
|
||||||
|
@ -1148,33 +1154,18 @@ mysql_execute_command(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(res=open_and_lock_tables(thd,tables)))
|
if (!(res=open_and_lock_tables(thd,tables)))
|
||||||
{
|
res=handle_select(thd, lex, result);
|
||||||
res=mysql_select(thd,tables,select_lex->item_list,
|
else
|
||||||
select_lex->where,
|
delete result;
|
||||||
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->abort();
|
|
||||||
}
|
|
||||||
delete result;
|
|
||||||
#ifdef DELETE_ITEMS
|
|
||||||
delete select_lex->having;
|
|
||||||
delete select_lex->where;
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_PURGE:
|
case SQLCOM_PURGE:
|
||||||
{
|
{
|
||||||
if (check_process_priv(thd))
|
if (check_process_priv(thd))
|
||||||
goto error;
|
goto error;
|
||||||
res = purge_master_logs(thd, lex->to_log);
|
res = purge_master_logs(thd, lex->to_log);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_SHOW_NEW_MASTER:
|
case SQLCOM_SHOW_NEW_MASTER:
|
||||||
{
|
{
|
||||||
if(check_access(thd, FILE_ACL, any_db))
|
if(check_access(thd, FILE_ACL, any_db))
|
||||||
|
@ -1197,45 +1188,45 @@ mysql_execute_command(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_BACKUP_TABLE:
|
case SQLCOM_BACKUP_TABLE:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd,tables) ||
|
if (check_db_used(thd,tables) ||
|
||||||
check_table_access(thd,SELECT_ACL, tables) ||
|
check_table_access(thd,SELECT_ACL, tables) ||
|
||||||
check_access(thd, FILE_ACL, any_db))
|
check_access(thd, FILE_ACL, any_db))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
res = mysql_backup_table(thd, tables);
|
res = mysql_backup_table(thd, tables);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_RESTORE_TABLE:
|
case SQLCOM_RESTORE_TABLE:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd,tables) ||
|
if (check_db_used(thd,tables) ||
|
||||||
check_table_access(thd,INSERT_ACL, tables) ||
|
check_table_access(thd,INSERT_ACL, tables) ||
|
||||||
check_access(thd, FILE_ACL, any_db))
|
check_access(thd, FILE_ACL, any_db))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
res = mysql_restore_table(thd, tables);
|
res = mysql_restore_table(thd, tables);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_CHANGE_MASTER:
|
case SQLCOM_CHANGE_MASTER:
|
||||||
{
|
{
|
||||||
if(check_access(thd, PROCESS_ACL, any_db))
|
if(check_access(thd, PROCESS_ACL, any_db))
|
||||||
goto error;
|
goto error;
|
||||||
res = change_master(thd);
|
res = change_master(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_SHOW_SLAVE_STAT:
|
case SQLCOM_SHOW_SLAVE_STAT:
|
||||||
{
|
{
|
||||||
if (check_process_priv(thd))
|
if (check_process_priv(thd))
|
||||||
goto error;
|
goto error;
|
||||||
res = show_master_info(thd);
|
res = show_master_info(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_SHOW_MASTER_STAT:
|
case SQLCOM_SHOW_MASTER_STAT:
|
||||||
{
|
{
|
||||||
if (check_process_priv(thd))
|
if (check_process_priv(thd))
|
||||||
goto error;
|
goto error;
|
||||||
res = show_binlog_info(thd);
|
res = show_binlog_info(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
case SQLCOM_LOAD_MASTER_DATA: // sync with master
|
||||||
if(check_process_priv(thd))
|
if(check_process_priv(thd))
|
||||||
|
@ -1257,7 +1248,7 @@ mysql_execute_command(void)
|
||||||
bool error=check_grant(thd,CREATE_ACL,tables);
|
bool error=check_grant(thd,CREATE_ACL,tables);
|
||||||
tables->next=tmp_table_list;
|
tables->next=tmp_table_list;
|
||||||
if (error)
|
if (error)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (strlen(tables->name) > NAME_LEN)
|
if (strlen(tables->name) > NAME_LEN)
|
||||||
{
|
{
|
||||||
|
@ -1304,6 +1295,8 @@ mysql_execute_command(void)
|
||||||
if (select_lex->item_list.elements) // With select
|
if (select_lex->item_list.elements) // With select
|
||||||
{
|
{
|
||||||
select_result *result;
|
select_result *result;
|
||||||
|
if ((res = create_total_list(thd,lex,&tables)))
|
||||||
|
break;
|
||||||
|
|
||||||
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
|
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||||
check_dup(thd,tables->db,tables->real_name,tables->next))
|
check_dup(thd,tables->db,tables->real_name,tables->next))
|
||||||
|
@ -1323,15 +1316,22 @@ mysql_execute_command(void)
|
||||||
thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
|
thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
|
||||||
if (thd->select_limit < select_lex->select_limit)
|
if (thd->select_limit < select_lex->select_limit)
|
||||||
thd->select_limit= HA_POS_ERROR; // No limit
|
thd->select_limit= HA_POS_ERROR; // No limit
|
||||||
if ((result=new select_create(tables->db ? tables->db : thd->db,
|
|
||||||
tables->real_name, &lex->create_info,
|
/* Skip first table, which is the table we are creating */
|
||||||
lex->create_list,
|
lex->select_lex.table_list.first=
|
||||||
lex->key_list,
|
(byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
|
||||||
select_lex->item_list,lex->duplicates)))
|
if (!(res=open_and_lock_tables(thd,tables->next)))
|
||||||
res=handle_create_select(thd,lex,result);
|
{
|
||||||
else
|
if ((result=new select_create(tables->db ? tables->db : thd->db,
|
||||||
res= -1;
|
tables->real_name, &lex->create_info,
|
||||||
}
|
lex->create_list,
|
||||||
|
lex->key_list,
|
||||||
|
select_lex->item_list,lex->duplicates)))
|
||||||
|
res=handle_select(thd, lex, result);
|
||||||
|
else
|
||||||
|
res= -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else // regular create
|
else // regular create
|
||||||
{
|
{
|
||||||
res = mysql_create_table(thd,tables->db ? tables->db : thd->db,
|
res = mysql_create_table(thd,tables->db ? tables->db : thd->db,
|
||||||
|
@ -1438,7 +1438,7 @@ mysql_execute_command(void)
|
||||||
old_list.next=new_list.next=0;
|
old_list.next=new_list.next=0;
|
||||||
if (check_grant(thd,ALTER_ACL,&old_list) ||
|
if (check_grant(thd,ALTER_ACL,&old_list) ||
|
||||||
(!test_all_bits(table->next->grant.privilege,
|
(!test_all_bits(table->next->grant.privilege,
|
||||||
INSERT_ACL | CREATE_ACL) &&
|
INSERT_ACL | CREATE_ACL) &&
|
||||||
check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list)))
|
check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list)))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -1476,21 +1476,21 @@ mysql_execute_command(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case SQLCOM_REPAIR:
|
case SQLCOM_REPAIR:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd,tables) ||
|
if (check_db_used(thd,tables) ||
|
||||||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
|
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
res = mysql_repair_table(thd, tables, &lex->check_opt);
|
res = mysql_repair_table(thd, tables, &lex->check_opt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_CHECK:
|
case SQLCOM_CHECK:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd,tables) ||
|
if (check_db_used(thd,tables) ||
|
||||||
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
|
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
|
||||||
goto error; /* purecov: inspected */
|
goto error; /* purecov: inspected */
|
||||||
res = mysql_check_table(thd, tables, &lex->check_opt);
|
res = mysql_check_table(thd, tables, &lex->check_opt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_ANALYZE:
|
case SQLCOM_ANALYZE:
|
||||||
{
|
{
|
||||||
if (check_db_used(thd,tables) ||
|
if (check_db_used(thd,tables) ||
|
||||||
|
@ -1574,6 +1574,9 @@ mysql_execute_command(void)
|
||||||
case SQLCOM_REPLACE_SELECT:
|
case SQLCOM_REPLACE_SELECT:
|
||||||
case SQLCOM_INSERT_SELECT:
|
case SQLCOM_INSERT_SELECT:
|
||||||
{
|
{
|
||||||
|
if ((res = create_total_list(thd,lex,&tables)))
|
||||||
|
break;
|
||||||
|
|
||||||
// Check that we have modify privileges for the first table and
|
// Check that we have modify privileges for the first table and
|
||||||
// select privileges for the rest
|
// select privileges for the rest
|
||||||
{
|
{
|
||||||
|
@ -1596,81 +1599,30 @@ mysql_execute_command(void)
|
||||||
if (thd->select_limit < select_lex->select_limit)
|
if (thd->select_limit < select_lex->select_limit)
|
||||||
thd->select_limit= HA_POS_ERROR; // No limit
|
thd->select_limit= HA_POS_ERROR; // No limit
|
||||||
|
|
||||||
if (lex->select_lex.next)
|
if (check_dup(thd,tables->db,tables->real_name,tables->next))
|
||||||
{
|
{
|
||||||
TABLE_LIST *total;
|
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
|
||||||
if ((res = create_total_list_and_check_acl(thd,lex,&total)))
|
DBUG_VOID_RETURN;
|
||||||
goto error;
|
|
||||||
if (check_dup(thd,total->db,total->real_name,total->next))
|
|
||||||
{
|
|
||||||
net_printf(&thd->net,ER_INSERT_TABLE_USED,total->real_name);
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
total->lock_type=TL_WRITE; // update first table
|
|
||||||
{
|
|
||||||
TABLE_LIST *table;
|
|
||||||
for (table = total->next ; table ; table=table->next)
|
|
||||||
table->lock_type= lex->lock_option;
|
|
||||||
}
|
|
||||||
if (!(res=open_and_lock_tables(thd, total)))
|
|
||||||
{
|
|
||||||
if ((result=new select_insert(total->table,&lex->field_list,
|
|
||||||
lex->sql_command == SQLCOM_REPLACE_SELECT ?
|
|
||||||
DUP_REPLACE : DUP_IGNORE)))
|
|
||||||
{
|
|
||||||
|
|
||||||
for (SELECT_LEX *sl=&lex->select_lex; sl; sl=sl->next)
|
|
||||||
{
|
|
||||||
TABLE_LIST *help=(TABLE_LIST *)sl->table_list.first;
|
|
||||||
if (sl==&lex->select_lex) help=help->next;
|
|
||||||
for (TABLE_LIST *cursor= help;
|
|
||||||
cursor;
|
|
||||||
cursor=cursor->next)
|
|
||||||
cursor->table= ((TABLE_LIST*) cursor->table)->table;
|
|
||||||
}
|
|
||||||
res=mysql_union(thd,lex,result);
|
|
||||||
}
|
|
||||||
close_thread_tables(thd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (check_dup(thd,tables->db,tables->real_name,tables->next))
|
|
||||||
{
|
|
||||||
net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
|
|
||||||
DBUG_VOID_RETURN;
|
|
||||||
}
|
|
||||||
tables->lock_type=TL_WRITE; // update first table
|
|
||||||
{
|
|
||||||
TABLE_LIST *table;
|
|
||||||
for (table = tables->next ; table ; table=table->next)
|
|
||||||
table->lock_type= lex->lock_option;
|
|
||||||
}
|
|
||||||
if (!(res=open_and_lock_tables(thd,tables)))
|
|
||||||
{
|
|
||||||
if ((result=new select_insert(tables->table,&lex->field_list,
|
|
||||||
lex->sql_command == SQLCOM_REPLACE_SELECT ?
|
|
||||||
DUP_REPLACE : DUP_IGNORE)))
|
|
||||||
{
|
|
||||||
res=mysql_select(thd,tables->next,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);
|
|
||||||
delete result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res= -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef DELETE_ITEMS
|
tables->lock_type=TL_WRITE; // update first table
|
||||||
delete select_lex->having;
|
{
|
||||||
delete select_lex->where;
|
TABLE_LIST *table;
|
||||||
#endif
|
for (table = tables->next ; table ; table=table->next)
|
||||||
|
table->lock_type= lex->lock_option;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip first table, which is the table we are inserting in */
|
||||||
|
lex->select_lex.table_list.first=
|
||||||
|
(byte*) (((TABLE_LIST *) lex->select_lex.table_list.first)->next);
|
||||||
|
if (!(res=open_and_lock_tables(thd, tables)))
|
||||||
|
{
|
||||||
|
if ((result=new select_insert(tables->table,&lex->field_list,
|
||||||
|
lex->sql_command == SQLCOM_REPLACE_SELECT ?
|
||||||
|
DUP_REPLACE : DUP_IGNORE)))
|
||||||
|
res=handle_select(thd,lex,result);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
res= -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_TRUNCATE:
|
case SQLCOM_TRUNCATE:
|
||||||
|
@ -1760,39 +1712,6 @@ mysql_execute_command(void)
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_UNION_SELECT:
|
|
||||||
{
|
|
||||||
TABLE_LIST *total;
|
|
||||||
if (select_lex->options & SELECT_DESCRIBE)
|
|
||||||
lex->exchange=0;
|
|
||||||
if ((res = create_total_list_and_check_acl(thd,lex,&total)) == -1)
|
|
||||||
{
|
|
||||||
res=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (res &&
|
|
||||||
(res=check_access(thd,
|
|
||||||
lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
|
|
||||||
any_db)))
|
|
||||||
{
|
|
||||||
res=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!(res=open_and_lock_tables(thd, total)))
|
|
||||||
{
|
|
||||||
/* Fix tables--to-be-unioned-from list to point at opened tables */
|
|
||||||
for (SELECT_LEX *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;
|
|
||||||
}
|
|
||||||
res=mysql_union(thd,lex);
|
|
||||||
}
|
|
||||||
close_thread_tables(thd);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SQLCOM_DROP_TABLE:
|
case SQLCOM_DROP_TABLE:
|
||||||
{
|
{
|
||||||
if (check_table_access(thd,DROP_ACL,tables))
|
if (check_table_access(thd,DROP_ACL,tables))
|
||||||
|
@ -1952,7 +1871,7 @@ mysql_execute_command(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
|
if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
|
||||||
grant_option && check_grant(thd,privilege,tables))
|
grant_option && check_grant(thd,privilege,tables))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
res=mysql_load(thd, lex->exchange, tables, lex->field_list,
|
res=mysql_load(thd, lex->exchange, tables, lex->field_list,
|
||||||
|
@ -2006,13 +1925,7 @@ mysql_execute_command(void)
|
||||||
end_active_trans(thd);
|
end_active_trans(thd);
|
||||||
}
|
}
|
||||||
if (thd->global_read_lock)
|
if (thd->global_read_lock)
|
||||||
{
|
unlock_global_read_lock(thd);
|
||||||
thd->global_read_lock=0;
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
|
||||||
global_read_lock--;
|
|
||||||
pthread_cond_broadcast(&COND_refresh);
|
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
|
||||||
}
|
|
||||||
send_ok(&thd->net);
|
send_ok(&thd->net);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_LOCK_TABLES:
|
case SQLCOM_LOCK_TABLES:
|
||||||
|
@ -2036,30 +1949,30 @@ mysql_execute_command(void)
|
||||||
thd->in_lock_tables=0;
|
thd->in_lock_tables=0;
|
||||||
break;
|
break;
|
||||||
case SQLCOM_CREATE_DB:
|
case SQLCOM_CREATE_DB:
|
||||||
|
{
|
||||||
|
if (!stripp_sp(lex->name) || check_db_name(lex->name))
|
||||||
{
|
{
|
||||||
if (!stripp_sp(lex->name) || check_db_name(lex->name))
|
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
||||||
{
|
|
||||||
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check_access(thd,CREATE_ACL,lex->name,0,1))
|
|
||||||
break;
|
|
||||||
mysql_create_db(thd,lex->name,lex->create_info.options);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (check_access(thd,CREATE_ACL,lex->name,0,1))
|
||||||
|
break;
|
||||||
|
mysql_create_db(thd,lex->name,lex->create_info.options);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_DROP_DB:
|
case SQLCOM_DROP_DB:
|
||||||
|
{
|
||||||
|
if (!stripp_sp(lex->name) || check_db_name(lex->name))
|
||||||
{
|
{
|
||||||
if (!stripp_sp(lex->name) || check_db_name(lex->name))
|
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
||||||
{
|
|
||||||
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (check_access(thd,DROP_ACL,lex->name,0,1) ||
|
|
||||||
end_active_trans(thd))
|
|
||||||
break;
|
|
||||||
mysql_rm_db(thd,lex->name,lex->drop_if_exists);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (check_access(thd,DROP_ACL,lex->name,0,1) ||
|
||||||
|
end_active_trans(thd))
|
||||||
|
break;
|
||||||
|
mysql_rm_db(thd,lex->name,lex->drop_if_exists);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SQLCOM_CREATE_FUNCTION:
|
case SQLCOM_CREATE_FUNCTION:
|
||||||
if (check_access(thd,INSERT_ACL,"mysql",0,1))
|
if (check_access(thd,INSERT_ACL,"mysql",0,1))
|
||||||
break;
|
break;
|
||||||
|
@ -2080,78 +1993,78 @@ mysql_execute_command(void)
|
||||||
res= -1;
|
res= -1;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case SQLCOM_REVOKE:
|
case SQLCOM_REVOKE:
|
||||||
case SQLCOM_GRANT:
|
case SQLCOM_GRANT:
|
||||||
{
|
{
|
||||||
if (tables && !tables->db)
|
if (tables && !tables->db)
|
||||||
tables->db=thd->db;
|
tables->db=thd->db;
|
||||||
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
|
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
|
||||||
tables && tables->db ? tables->db : select_lex->db,
|
tables && tables->db ? tables->db : select_lex->db,
|
||||||
tables ? &tables->grant.privilege : 0,
|
tables ? &tables->grant.privilege : 0,
|
||||||
tables ? 0 : 1))
|
tables ? 0 : 1))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
/* Check that the user isn't trying to change a password for another
|
/* Check that the user isn't trying to change a password for another
|
||||||
user if he doesn't have UPDATE privilege to the MySQL database */
|
user if he doesn't have UPDATE privilege to the MySQL database */
|
||||||
|
|
||||||
if (thd->user) // If not replication
|
if (thd->user) // If not replication
|
||||||
{
|
{
|
||||||
LEX_USER *user;
|
LEX_USER *user;
|
||||||
List_iterator <LEX_USER> user_list(lex->users_list);
|
List_iterator <LEX_USER> user_list(lex->users_list);
|
||||||
while ((user=user_list++))
|
while ((user=user_list++))
|
||||||
{
|
{
|
||||||
if (user->password.str &&
|
if (user->password.str &&
|
||||||
(strcmp(thd->user,user->user.str) ||
|
(strcmp(thd->user,user->user.str) ||
|
||||||
user->host.str &&
|
user->host.str &&
|
||||||
my_strcasecmp(user->host.str, thd->host ? thd->host : thd->ip)))
|
my_strcasecmp(user->host.str, thd->host_or_ip)))
|
||||||
{
|
{
|
||||||
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
|
if (check_access(thd, UPDATE_ACL, "mysql",0,1))
|
||||||
goto error;
|
goto error;
|
||||||
break; // We are allowed to do changes
|
break; // We are allowed to do changes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tables)
|
if (tables)
|
||||||
{
|
{
|
||||||
if (grant_option && check_grant(thd,
|
if (grant_option && check_grant(thd,
|
||||||
(lex->grant | lex->grant_tot_col |
|
(lex->grant | lex->grant_tot_col |
|
||||||
GRANT_ACL),
|
GRANT_ACL),
|
||||||
tables))
|
tables))
|
||||||
goto error;
|
goto error;
|
||||||
res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
|
res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
|
||||||
lex->grant, lex->sql_command == SQLCOM_REVOKE);
|
lex->grant, lex->sql_command == SQLCOM_REVOKE);
|
||||||
if(!res)
|
if(!res)
|
||||||
{
|
{
|
||||||
mysql_update_log.write(thd, thd->query,thd->query_length);
|
mysql_update_log.write(thd, thd->query,thd->query_length);
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
Query_log_event qinfo(thd, thd->query);
|
Query_log_event qinfo(thd, thd->query);
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lex->columns.elements)
|
if (lex->columns.elements)
|
||||||
{
|
{
|
||||||
net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
|
net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
|
||||||
res=1;
|
res=1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
|
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
|
||||||
lex->sql_command == SQLCOM_REVOKE);
|
lex->sql_command == SQLCOM_REVOKE);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
mysql_update_log.write(thd, thd->query,thd->query_length);
|
mysql_update_log.write(thd, thd->query,thd->query_length);
|
||||||
if (mysql_bin_log.is_open())
|
if (mysql_bin_log.is_open())
|
||||||
{
|
{
|
||||||
Query_log_event qinfo(thd, thd->query);
|
Query_log_event qinfo(thd, thd->query);
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_FLUSH:
|
case SQLCOM_FLUSH:
|
||||||
case SQLCOM_RESET:
|
case SQLCOM_RESET:
|
||||||
if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
|
if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
|
||||||
|
@ -2166,14 +2079,16 @@ mysql_execute_command(void)
|
||||||
break;
|
break;
|
||||||
case SQLCOM_SHOW_GRANTS:
|
case SQLCOM_SHOW_GRANTS:
|
||||||
res=0;
|
res=0;
|
||||||
if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
|
if ((thd->priv_user &&
|
||||||
|
!strcmp(thd->priv_user,lex->grant_user->user.str)) ||
|
||||||
!check_access(thd, SELECT_ACL, "mysql",0,1))
|
!check_access(thd, SELECT_ACL, "mysql",0,1))
|
||||||
{
|
{
|
||||||
res = mysql_show_grants(thd,lex->grant_user);
|
res = mysql_show_grants(thd,lex->grant_user);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SQLCOM_HA_OPEN:
|
case SQLCOM_HA_OPEN:
|
||||||
if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL, tables))
|
if (check_db_used(thd,tables) ||
|
||||||
|
check_table_access(thd,SELECT_ACL, tables))
|
||||||
goto error;
|
goto error;
|
||||||
res = mysql_ha_open(thd, tables);
|
res = mysql_ha_open(thd, tables);
|
||||||
break;
|
break;
|
||||||
|
@ -2183,11 +2098,12 @@ mysql_execute_command(void)
|
||||||
res = mysql_ha_close(thd, tables);
|
res = mysql_ha_close(thd, tables);
|
||||||
break;
|
break;
|
||||||
case SQLCOM_HA_READ:
|
case SQLCOM_HA_READ:
|
||||||
if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL, tables))
|
if (check_db_used(thd,tables) ||
|
||||||
|
check_table_access(thd,SELECT_ACL, tables))
|
||||||
goto error;
|
goto error;
|
||||||
res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
|
res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
|
||||||
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
||||||
select_lex->select_limit, select_lex->offset_limit);
|
select_lex->select_limit, select_lex->offset_limit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQLCOM_BEGIN:
|
case SQLCOM_BEGIN:
|
||||||
|
@ -2278,7 +2194,7 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
|
||||||
{ // We can never grant this
|
{ // We can never grant this
|
||||||
net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
|
net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
|
||||||
thd->priv_user,
|
thd->priv_user,
|
||||||
thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
|
thd->host_or_ip,
|
||||||
thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
|
thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
|
||||||
return TRUE; /* purecov: tested */
|
return TRUE; /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
@ -2301,7 +2217,7 @@ check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
|
||||||
return FALSE; /* Ok */
|
return FALSE; /* Ok */
|
||||||
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,
|
||||||
db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
|
db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
|
||||||
return TRUE; /* purecov: tested */
|
return TRUE; /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
@ -2458,7 +2374,6 @@ mysql_init_query(THD *thd)
|
||||||
thd->fatal_error=0; // Safety
|
thd->fatal_error=0; // Safety
|
||||||
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
|
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
|
||||||
thd->sent_row_count=thd->examined_row_count=0;
|
thd->sent_row_count=thd->examined_row_count=0;
|
||||||
thd->lex.sql_command=SQLCOM_NONE;
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2470,7 +2385,7 @@ mysql_init_select(LEX *lex)
|
||||||
select_lex->select_limit=current_thd->default_select_limit;
|
select_lex->select_limit=current_thd->default_select_limit;
|
||||||
select_lex->offset_limit=0;
|
select_lex->offset_limit=0;
|
||||||
select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE;
|
select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE;
|
||||||
select_lex->select_number = 0; lex->exchange = 0;
|
lex->exchange = 0;
|
||||||
lex->proc_list.first=0;
|
lex->proc_list.first=0;
|
||||||
select_lex->order_list.elements=select_lex->group_list.elements=0;
|
select_lex->order_list.elements=select_lex->group_list.elements=0;
|
||||||
select_lex->order_list.first=0;
|
select_lex->order_list.first=0;
|
||||||
|
@ -2483,12 +2398,9 @@ mysql_init_select(LEX *lex)
|
||||||
void
|
void
|
||||||
mysql_new_select(LEX *lex)
|
mysql_new_select(LEX *lex)
|
||||||
{
|
{
|
||||||
uint select_no=lex->select->select_number;
|
|
||||||
SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
|
SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX));
|
||||||
lex->select->next=select_lex;
|
lex->select->next=select_lex;
|
||||||
lex->select=select_lex; select_lex->select_number = ++select_no;
|
lex->select=select_lex;
|
||||||
select_lex->table_list.elements=0;
|
|
||||||
select_lex->table_list.first=0;
|
|
||||||
select_lex->table_list.next= (byte**) &select_lex->table_list.first;
|
select_lex->table_list.next= (byte**) &select_lex->table_list.first;
|
||||||
select_lex->item_list.empty(); select_lex->when_list.empty();
|
select_lex->item_list.empty(); select_lex->when_list.empty();
|
||||||
select_lex->expr_list.empty(); select_lex->interval_list.empty();
|
select_lex->expr_list.empty(); select_lex->interval_list.empty();
|
||||||
|
@ -2871,7 +2783,6 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
register TABLE_LIST *ptr;
|
register TABLE_LIST *ptr;
|
||||||
THD *thd=current_thd;
|
THD *thd=current_thd;
|
||||||
char *alias_str;
|
char *alias_str;
|
||||||
const char *current_db;
|
|
||||||
DBUG_ENTER("add_table_to_list");
|
DBUG_ENTER("add_table_to_list");
|
||||||
|
|
||||||
if (!table)
|
if (!table)
|
||||||
|
@ -2887,14 +2798,14 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
|
|
||||||
#ifdef FN_LOWER_CASE
|
#ifdef FN_LOWER_CASE
|
||||||
if (!alias) /* Alias is case sensitive */
|
if (!alias) /* Alias is case sensitive */
|
||||||
if (!(alias_str=sql_strmake(alias_str,table->table.length)))
|
if (!(alias_str=thd->memdup(alias_str,table->table.length+1)))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
if (lower_case_table_names)
|
if (lower_case_table_names)
|
||||||
casedn_str(table->table.str);
|
casedn_str(table->table.str);
|
||||||
#endif
|
#endif
|
||||||
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
||||||
DBUG_RETURN(0); /* purecov: inspected */
|
DBUG_RETURN(0); /* purecov: inspected */
|
||||||
ptr->db= table->db.str;
|
ptr->db= table->db.str ? table->db.str : (thd->db ? thd->db : (char*) "");
|
||||||
ptr->real_name=table->table.str;
|
ptr->real_name=table->table.str;
|
||||||
ptr->name=alias_str;
|
ptr->name=alias_str;
|
||||||
ptr->lock_type=flags;
|
ptr->lock_type=flags;
|
||||||
|
@ -2907,16 +2818,12 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
sizeof(*ignore_index));
|
sizeof(*ignore_index));
|
||||||
|
|
||||||
/* check that used name is unique */
|
/* check that used name is unique */
|
||||||
current_db=thd->db ? thd->db : "";
|
|
||||||
|
|
||||||
if (flags != TL_IGNORE)
|
if (flags != TL_IGNORE)
|
||||||
{
|
{
|
||||||
for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ; tables ;
|
for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ; tables ;
|
||||||
tables=tables->next)
|
tables=tables->next)
|
||||||
{
|
{
|
||||||
if (!strcmp(alias_str,tables->name) &&
|
if (!strcmp(alias_str,tables->name) && !strcmp(ptr->db, tables->db))
|
||||||
!strcmp(ptr->db ? ptr->db : current_db,
|
|
||||||
tables->db ? tables->db : current_db))
|
|
||||||
{
|
{
|
||||||
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
|
net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
|
||||||
DBUG_RETURN(0); /* purecov: tested */
|
DBUG_RETURN(0); /* purecov: tested */
|
||||||
|
@ -2934,40 +2841,37 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
|
||||||
** to the entries in this list.
|
** to the entries in this list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int create_total_list_and_check_acl(THD *thd, LEX *lex,
|
static int create_total_list(THD *thd, LEX *lex, TABLE_LIST **result)
|
||||||
TABLE_LIST **result, bool skip_first = false)
|
|
||||||
{
|
{
|
||||||
|
/* Handle the case when we are not using union */
|
||||||
|
if (!lex->select_lex.next)
|
||||||
|
{
|
||||||
|
*result= (TABLE_LIST*) lex->select_lex.table_list.first;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
SELECT_LEX *sl;
|
SELECT_LEX *sl;
|
||||||
TABLE_LIST **new_table_list= result, *aux;
|
TABLE_LIST **new_table_list= result, *aux;
|
||||||
const char *current_db=thd->db ? thd->db : ""; // QQ; To be removed
|
|
||||||
|
|
||||||
*new_table_list=0; // end result list
|
*new_table_list=0; // end result list
|
||||||
for (sl= &lex->select_lex; sl; sl=sl->next)
|
for (sl= &lex->select_lex; sl; sl=sl->next)
|
||||||
{
|
{
|
||||||
if ((lex->sql_command == SQLCOM_UNION_SELECT) &&
|
if (sl->order_list.first && sl->next)
|
||||||
sl->order_list.first && sl->next)
|
|
||||||
{
|
{
|
||||||
net_printf(&thd->net,ER_WRONG_USAGE,"UNION","ORDER BY");
|
my_error(ER_WRONG_USAGE,MYF(0),"UNION","ORDER BY");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
aux= (TABLE_LIST*) sl->table_list.first;
|
if ((aux= (TABLE_LIST*) sl->table_list.first))
|
||||||
if (skip_first && sl == &lex->select_lex) aux=aux->next;
|
|
||||||
if (aux)
|
|
||||||
{
|
{
|
||||||
TABLE_LIST *next;
|
TABLE_LIST *next;
|
||||||
if (check_table_access(thd,
|
|
||||||
lex->exchange ?
|
|
||||||
SELECT_ACL | FILE_ACL : SELECT_ACL , aux))
|
|
||||||
return -1;
|
|
||||||
for (; aux; aux=next)
|
for (; aux; aux=next)
|
||||||
{
|
{
|
||||||
TABLE_LIST *cursor;
|
TABLE_LIST *cursor;
|
||||||
next= aux->next;
|
next= aux->next;
|
||||||
if (!aux->db)
|
|
||||||
aux->db=(char *)current_db; // QQ; To be removed
|
|
||||||
for (cursor= *result; cursor; cursor=cursor->next)
|
for (cursor= *result; cursor; cursor=cursor->next)
|
||||||
if (!strcmp(cursor->db,aux->db) &&
|
if (!strcmp(cursor->db,aux->db) &&
|
||||||
(!strcmp(cursor->real_name,aux->real_name)))
|
!strcmp(cursor->real_name,aux->real_name) &&
|
||||||
|
!strcmp(cursor->name, aux->name))
|
||||||
break;
|
break;
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
{
|
{
|
||||||
|
@ -2975,7 +2879,7 @@ static int create_total_list_and_check_acl(THD *thd, LEX *lex,
|
||||||
aux->lock_type= lex->lock_option;
|
aux->lock_type= lex->lock_option;
|
||||||
if (!(cursor = (TABLE_LIST *) thd->memdup((byte*) aux,
|
if (!(cursor = (TABLE_LIST *) thd->memdup((byte*) aux,
|
||||||
sizeof(*aux))))
|
sizeof(*aux))))
|
||||||
return 1;
|
return -1;
|
||||||
*new_table_list= cursor;
|
*new_table_list= cursor;
|
||||||
new_table_list= &cursor->next;
|
new_table_list= &cursor->next;
|
||||||
*new_table_list=0; // end result list
|
*new_table_list=0; // end result list
|
||||||
|
@ -2987,51 +2891,6 @@ static int create_total_list_and_check_acl(THD *thd, LEX *lex,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_create_select(THD *thd, LEX *lex, select_result *c_i)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
if (lex->select_lex.next)
|
|
||||||
{
|
|
||||||
TABLE_LIST *total;
|
|
||||||
if ((res = create_total_list_and_check_acl(thd,lex,&total,true)))
|
|
||||||
return res;
|
|
||||||
if (!(res=open_and_lock_tables(thd, total)))
|
|
||||||
{
|
|
||||||
for (SELECT_LEX *sl=&lex->select_lex; sl; sl=sl->next)
|
|
||||||
{
|
|
||||||
TABLE_LIST *help=(TABLE_LIST *)sl->table_list.first;
|
|
||||||
if (sl==&lex->select_lex) help=help->next;
|
|
||||||
for (TABLE_LIST *cursor= help;
|
|
||||||
cursor;
|
|
||||||
cursor=cursor->next)
|
|
||||||
cursor->table= ((TABLE_LIST*) cursor->table)->table;
|
|
||||||
}
|
|
||||||
res=mysql_union(thd,lex,c_i);
|
|
||||||
}
|
|
||||||
close_thread_tables(thd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TABLE_LIST *tables=(TABLE_LIST*) lex->select_lex.table_list.first;
|
|
||||||
SELECT_LEX *select_lex=&lex->select_lex;
|
|
||||||
if (!(res=open_and_lock_tables(thd,tables->next)))
|
|
||||||
{
|
|
||||||
res=mysql_select(thd,tables->next,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,
|
|
||||||
c_i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (res)
|
|
||||||
c_i->abort();
|
|
||||||
delete c_i;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_join_on(TABLE_LIST *b,Item *expr)
|
void add_join_on(TABLE_LIST *b,Item *expr)
|
||||||
{
|
{
|
||||||
|
@ -3055,10 +2914,8 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
|
||||||
static bool check_dup(THD *thd,const char *db,const char *name,
|
static bool check_dup(THD *thd,const char *db,const char *name,
|
||||||
TABLE_LIST *tables)
|
TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
const char *thd_db=thd->db ? thd->db : any_db;
|
|
||||||
for (; tables ; tables=tables->next)
|
for (; tables ; tables=tables->next)
|
||||||
if (!strcmp(name,tables->real_name) &&
|
if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db))
|
||||||
!strcmp(db ? db : thd_db, tables->db ? tables->db : thd_db))
|
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3085,10 +2942,10 @@ bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
|
||||||
}
|
}
|
||||||
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
|
if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
|
||||||
{
|
{
|
||||||
if ((options & REFRESH_READ_LOCK) && thd && ! thd->global_read_lock)
|
if ((options & REFRESH_READ_LOCK) && thd)
|
||||||
{
|
{
|
||||||
thd->global_read_lock=1;
|
if (lock_global_read_lock(thd))
|
||||||
thread_safe_increment(global_read_lock,&LOCK_open);
|
return 1;
|
||||||
}
|
}
|
||||||
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
|
result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,26 +1043,26 @@ 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;
|
||||||
}
|
}
|
||||||
delete ev;
|
delete 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 slave event in log '%s'",
|
"Error reading slave event in log '%s'",
|
||||||
(char*)log_file_name);
|
(char*)log_file_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
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)
|
||||||
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 :
|
||||||
"system user" : "unauthenticated user"));
|
(tmp->system_thread ?
|
||||||
thd_info->host=thd->strdup(tmp->host ? tmp->host : (tmp->ip ? tmp->ip :
|
"system user" : "unauthenticated user"));
|
||||||
(tmp->system_thread ? "none" : "connecting host")));
|
thd_info->host=thd->strdup(tmp->host ? tmp->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 @@
|
||||||
#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 *
|
||||||
|
|
||||||
/* 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 *
|
||||||
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 *
|
||||||
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 *
|
||||||
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,11 +1317,16 @@ 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);
|
||||||
}
|
}
|
||||||
select_options select_item_list select_into select_lock_type union
|
select_options select_item_list select_into select_lock_type union
|
||||||
|
|
||||||
|
@ -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:
|
||||||
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 */ {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue