summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-06-30 19:34:54 +0300
committerunknown <monty@hundin.mysql.fi>2002-06-30 19:34:54 +0300
commit417c53ac5d26d4465d847d8c1a65b9847f8508a7 (patch)
treea9b44d5572a490b782837b066152336770b59740 /sql
parent422d3873af935a3720ba869a866e17136dc2e99c (diff)
parenta86390f01ae108baf07707d401e35c3c4e1e9041 (diff)
downloadmariadb-git-417c53ac5d26d4465d847d8c1a65b9847f8508a7.tar.gz
Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
include/my_pthread.h: Auto merged
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc34
-rw-r--r--sql/item_create.cc4
-rw-r--r--sql/item_create.h2
-rw-r--r--sql/item_func.cc32
-rw-r--r--sql/item_func.h4
-rw-r--r--sql/lex.h2
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_select.cc161
-rw-r--r--sql/table.cc3
11 files changed, 147 insertions, 113 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index ca0044b371a..90e8a0e451f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1625,17 +1625,41 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
}
}
+
+/*
+ Make a logical XOR of the arguments.
+
+ SYNOPSIS
+ val_int()
+
+ DESCRIPTION
+ If either operator is NULL, return NULL.
+
+ NOTE
+ As we don't do any index optimization on XOR this is not going to be
+ very fast to use.
+
+ TODO (low priority)
+ Change this to be optimized as:
+ A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
+ To be able to do this, we would however first have to extend the MySQL
+ range optimizer to handle OR better.
+*/
+
longlong Item_cond_xor::val_int()
{
List_iterator<Item> li(list);
Item *item;
int result=0;
- null_value=1;
+ null_value=0;
while ((item=li++))
{
- result ^= (item->val_int() != 0);
- if (!item->null_value)
- null_value=0;
+ result^= (item->val_int() != 0);
+ if (item->null_value)
+ {
+ null_value=1;
+ return 0;
+ }
}
- return result;
+ return (longlong) result;
}
diff --git a/sql/item_create.cc b/sql/item_create.cc
index f268550d115..62f09f002d1 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -429,9 +429,9 @@ Item *create_func_cast(Item *a, Item_cast cast_type)
return res;
}
-Item *create_func_check_lock(Item* a)
+Item *create_func_is_free_lock(Item* a)
{
current_thd->safe_to_cache_query=0;
- return new Item_func_check_lock(a);
+ return new Item_func_is_free_lock(a);
}
diff --git a/sql/item_create.h b/sql/item_create.h
index 09d72f9fbb3..967de0e2eba 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -91,4 +91,4 @@ Item *create_func_version(void);
Item *create_func_weekday(Item* a);
Item *create_load_file(Item* a);
Item *create_wait_for_master_pos(Item* a, Item* b);
-Item *create_func_check_lock(Item* a);
+Item *create_func_is_free_lock(Item* a);
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 4dfd9e3585f..a81a736c304 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2260,18 +2260,9 @@ double Item_func_match::val()
longlong Item_func_bit_xor::val_int()
{
ulonglong arg1= (ulonglong) args[0]->val_int();
- if (args[0]->null_value)
- {
- null_value=1;
- return 0;
- }
ulonglong arg2= (ulonglong) args[1]->val_int();
- if (args[1]->null_value)
- {
- null_value=1;
+ if ((null_value= (args[0]->null_value || args[1]->null_value)))
return 0;
- }
- null_value=0;
return (longlong) (arg1 ^ arg2);
}
@@ -2295,12 +2286,17 @@ Item *get_system_var(LEX_STRING name)
/*
Check a user level lock.
- Returns 1: available
- Returns 0: already taken
- Returns NULL: Error
+
+ SYNOPSIS:
+ val_int()
+
+ RETURN VALUES
+ 1 Available
+ 0 Already taken
+ NULL Error
*/
-longlong Item_func_check_lock::val_int()
+longlong Item_func_is_free_lock::val_int()
{
String *res=args[0]->val_str(&value);
struct timespec abstime;
@@ -2309,23 +2305,17 @@ longlong Item_func_check_lock::val_int()
int error=0;
null_value=0;
-
- if (/* check_global_access(thd,SUPER_ACL) ||*/ !res || !res->length())
+ if (!res || !res->length())
{
null_value=1;
return 0;
}
pthread_mutex_lock(&LOCK_user_locks);
-
-
ull= (ULL*) hash_search(&hash_user_locks,(byte*) res->ptr(),
res->length());
-
pthread_mutex_unlock(&LOCK_user_locks);
-
if (!ull || !ull->locked)
return 1;
-
return 0;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 0e1b5b7c9e0..5560d3cdb0d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1000,11 +1000,11 @@ public:
void fix_length_xor_dec() { unsigned_flag=1; }
};
-class Item_func_check_lock :public Item_int_func
+class Item_func_is_free_lock :public Item_int_func
{
String value;
public:
- Item_func_check_lock(Item *a) :Item_int_func(a) {}
+ Item_func_is_free_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "check_lock"; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
diff --git a/sql/lex.h b/sql/lex.h
index 8b9d2f3a9e0..81d597c6a5c 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -413,7 +413,6 @@ static SYMBOL sql_functions[] = {
{ "BIT_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
{ "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
{ "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
- { "CHECK_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_check_lock)},
{ "COALESCE", SYM(COALESCE),0,0},
{ "CONCAT", SYM(CONCAT),0,0},
{ "CONCAT_WS", SYM(CONCAT_WS),0,0},
@@ -458,6 +457,7 @@ static SYMBOL sql_functions[] = {
{ "INET_NTOA", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)},
{ "INSTR", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
{ "ISNULL", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
+ { "IS_FREE_LOCK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
{ "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
{ "LEAST", SYM(LEAST_SYM),0,0},
{ "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f1e863b830e..0b11ee89c3f 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1014,8 +1014,6 @@ static void server_init(void)
unireg_abort(1);
}
}
- if (mysqld_chroot)
- set_root(mysqld_chroot);
set_user(mysqld_user); // Works also with mysqld_user==NULL
#ifdef __NT__
@@ -1838,7 +1836,7 @@ int main(int argc, char **argv)
init_signals();
if (set_default_charset_by_name(default_charset, MYF(MY_WME)))
- exit( 1 );
+ exit(1);
charsets_list = list_charsets(MYF(MY_COMPILED_SETS|MY_CONFIG_SETS));
#ifdef HAVE_OPENSSL
@@ -1906,7 +1904,7 @@ int main(int argc, char **argv)
unireg_abort(1);
/*
- ** We have enough space for fiddling with the argv, continue
+ We have enough space for fiddling with the argv, continue
*/
umask(((~my_umask) & 0666));
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
@@ -4430,6 +4428,8 @@ static void get_options(int argc,char **argv)
if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
exit(ho_error);
+ if (mysqld_chroot)
+ set_root(mysqld_chroot);
fix_paths();
default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c37dc1c4f6e..6ea815cd51a 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -344,6 +344,8 @@ bool mysql_change_db(THD *thd,const char *name)
x_free(dbname);
DBUG_RETURN(1);
}
+ if (lower_case_table_names)
+ casedn_str(dbname);
DBUG_PRINT("info",("Use database: %s", dbname));
if (test_all_bits(thd->master_access,DB_ACLS))
db_access=DB_ACLS;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 783a1631fad..df44a7e043f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1035,6 +1035,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
+ if (lower_case_table_names)
+ casedn_str(db);
if (check_access(thd,CREATE_ACL,db,0,1))
break;
mysql_log.write(thd,command,packet);
@@ -1051,6 +1053,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
break;
}
+ if (lower_case_table_names)
+ casedn_str(db);
if (thd->locked_tables || thd->active_transaction())
{
send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION);
@@ -2239,6 +2243,8 @@ mysql_execute_command(void)
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break;
}
+ if (lower_case_table_names)
+ casedn_str(lex->name);
if (check_access(thd,CREATE_ACL,lex->name,0,1))
break;
res=mysql_create_db(thd,lex->name,lex->create_info.options,0);
@@ -2251,6 +2257,8 @@ mysql_execute_command(void)
net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
break;
}
+ if (lower_case_table_names)
+ casedn_str(lex->name);
if (check_access(thd,DROP_ACL,lex->name,0,1))
break;
if (thd->locked_tables || thd->active_transaction())
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0af91c443a8..459c85a4108 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -62,7 +62,7 @@ static void update_depend_map(JOIN *join);
static void update_depend_map(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool *simple_order);
-static int return_zero_rows(select_result *res,TABLE_LIST *tables,
+static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
List<Item> &fields, bool send_row,
uint select_options, const char *info,
Item *having, Procedure *proc);
@@ -145,7 +145,7 @@ static void init_sum_functions(Item_sum **func);
static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
bool distinct, const char *message=NullS);
-static void describe_info(THD *thd, const char *info);
+static void describe_info(JOIN *join, const char *info);
/*
This handles SELECT with and without UNION
@@ -187,7 +187,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
TABLE *tmp_table;
int error, tmp_error;
bool need_tmp,hidden_group_fields;
- bool simple_order,simple_group,no_order, skip_sort_order, buffer_result;
+ bool simple_order,simple_group,no_order, skip_sort_order;
Item::cond_result cond_value;
SQL_SELECT *select;
DYNAMIC_ARRAY keyuse;
@@ -202,7 +202,6 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
/* Check that all tables, fields, conds and order are ok */
select_distinct=test(select_options & SELECT_DISTINCT);
- buffer_result=test(select_options & OPTION_BUFFER_RESULT) && !test(select_options & OPTION_FOUND_ROWS);
tmp_table=0;
select=0;
no_order=skip_sort_order=0;
@@ -353,13 +352,10 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (cond_value == Item::COND_FALSE || !thd->select_limit)
{ /* Impossible cond */
- if (select_options & SELECT_DESCRIBE && select_lex->next)
- select_describe(&join,false,false,false,"Impossible WHERE");
- else
- error=return_zero_rows(result, tables, fields,
- join.tmp_table_param.sum_func_count != 0 && !group,
- select_options,"Impossible WHERE",having,
- procedure);
+ error=return_zero_rows(&join, result, tables, fields,
+ join.tmp_table_param.sum_func_count != 0 && !group,
+ select_options,"Impossible WHERE",having,
+ procedure);
delete procedure;
DBUG_RETURN(error);
}
@@ -372,21 +368,15 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{
if (res < 0)
{
- if (select_options & SELECT_DESCRIBE && select_lex->next)
- select_describe(&join,false,false,false,"No matching min/max row");
- else
- error=return_zero_rows(result, tables, fields, !group,
- select_options,"No matching min/max row",
- having,procedure);
+ error=return_zero_rows(&join, result, tables, fields, !group,
+ select_options,"No matching min/max row",
+ having,procedure);
delete procedure;
DBUG_RETURN(error);
}
if (select_options & SELECT_DESCRIBE)
{
- if (select_lex->next)
- select_describe(&join,false,false,false,"Select tables optimized away");
- else
- describe_info(thd,"Select tables optimized away");
+ describe_info(&join, "Select tables optimized away");
delete procedure;
DBUG_RETURN(error);
}
@@ -397,12 +387,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
{ // Only test of functions
error=0;
if (select_options & SELECT_DESCRIBE)
- {
- if (select_lex->next)
- select_describe(&join,false,false,false,"No tables used");
- else
- describe_info(thd,"No tables used");
- }
+ describe_info(&join, "No tables used");
else
{
result->send_fields(fields,1);
@@ -435,7 +420,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if (join.const_table_map != join.found_const_table_map &&
!(select_options & SELECT_DESCRIBE))
{
- error=return_zero_rows(result,tables,fields,
+ error=return_zero_rows(&join,result,tables,fields,
join.tmp_table_param.sum_func_count != 0 &&
!group,0,"",having,procedure);
goto err;
@@ -480,14 +465,11 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
}
if (make_join_select(&join,select,conds))
{
- if (select_options & SELECT_DESCRIBE && select_lex->next)
- select_describe(&join,false,false,false,"Impossible WHERE noticed after reading const tables");
- else
- error=return_zero_rows(result,tables,fields,
- join.tmp_table_param.sum_func_count != 0 && !group,
- select_options,
- "Impossible WHERE noticed after reading const tables",
- having,procedure);
+ error=return_zero_rows(&join, result, tables, fields,
+ join.tmp_table_param.sum_func_count != 0 && !group,
+ select_options,
+ "Impossible WHERE noticed after reading const tables",
+ having,procedure);
goto err;
}
@@ -546,21 +528,33 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
simple_order=0;
}
+ /*
+ Check if we need to create a temporary table.
+ This has to be done if all tables are not already read (const tables)
+ and one of the following conditions holds:
+ - We are using DISTINCT (simple distinct's are already optimized away)
+ - We are using an ORDER BY or GROUP BY on fields not in the first table
+ - We are using different ORDER BY and GROUP BY orders
+ - The user wants us to buffer the result.
+ */
need_tmp= (join.const_tables != join.tables &&
((select_distinct || !simple_order || !simple_group) ||
- (group && order) || buffer_result));
+ (group && order) ||
+ test(select_options & OPTION_BUFFER_RESULT)));
// No cache for MATCH
make_join_readinfo(&join,
(select_options & (SELECT_DESCRIBE |
SELECT_NO_JOIN_CACHE)) |
- (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE : 0));
-
- /* Need to tell Innobase that to play it safe, it should fetch all
- columns of the tables: this is because MySQL
- may build row pointers for the rows, and for all columns of the primary
- key the field->query_id has not necessarily been set to thd->query_id
- by MySQL. */
+ (cur_sel->ftfunc_list.elements ? SELECT_NO_JOIN_CACHE :
+ 0));
+ /*
+ Need to tell Innobase that to play it safe, it should fetch all
+ columns of the tables: this is because MySQL may build row
+ pointers for the rows, and for all columns of the primary key the
+ field->query_id has not necessarily been set to thd->query_id by
+ MySQL.
+ */
#ifdef HAVE_INNOBASE_DB
if (need_tmp || select_distinct || group || order)
@@ -2929,16 +2923,17 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order)
DBUG_RETURN(first_order);
}
+
static int
-return_zero_rows(select_result *result,TABLE_LIST *tables,List<Item> &fields,
- bool send_row, uint select_options,const char *info,
- Item *having, Procedure *procedure)
+return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
+ List<Item> &fields, bool send_row, uint select_options,
+ const char *info, Item *having, Procedure *procedure)
{
DBUG_ENTER("return_zero_rows");
if (select_options & SELECT_DESCRIBE)
- {
- describe_info(current_thd, info);
+ {
+ describe_info(join, info);
DBUG_RETURN(0);
}
if (procedure)
@@ -7007,6 +7002,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
MYSQL_LOCK *save_lock;
SELECT_LEX *select_lex = &(join->thd->lex.select_lex);
select_result *result=join->result;
+ Item *item_null= new Item_null();
DBUG_ENTER("select_describe");
/* Don't log this into the slow query log */
@@ -7034,13 +7030,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (message)
{
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
- item_list.push_back(new Item_empty_string("",0));
+ Item *empty= new Item_empty_string("",0);
+ for (uint i=0 ; i < 7; i++)
+ item_list.push_back(empty);
item_list.push_back(new Item_string(message,strlen(message)));
if (result->send_data(item_list))
result->send_error(0,NullS);
@@ -7053,15 +7045,19 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
JOIN_TAB *tab=join->join_tab+i;
TABLE *table=tab->table;
char buff[512],*buff_ptr=buff;
- char buff1[512], buff2[512], bufff[512];
+ char buff1[512], buff2[512], buff3[512];
String tmp1(buff1,sizeof(buff1));
String tmp2(buff2,sizeof(buff2));
+ tmp1.length(0);
+ tmp2.length(0);
item_list.empty();
+
if (tab->type == JT_ALL && tab->select && tab->select->quick)
tab->type= JT_RANGE;
- item_list.push_back(new Item_string(table->table_name,strlen(table->table_name)));
- item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type])));
- tmp1.length(0); tmp2.length(0);
+ item_list.push_back(new Item_string(table->table_name,
+ strlen(table->table_name)));
+ item_list.push_back(new Item_string(join_type_str[tab->type],
+ strlen(join_type_str[tab->type])));
key_map bits;
uint j;
for (j=0,bits=tab->keys ; bits ; j++,bits>>=1)
@@ -7076,11 +7072,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
if (tmp1.length())
item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length()));
else
- item_list.push_back(new Item_null());
+ item_list.push_back(item_null);
if (tab->ref.key_parts)
{
- item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,
- strlen(table->key_info[tab->ref.key].name)));
+ KEY *key_info=table->key_info+ tab->ref.key;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
item_list.push_back(new Item_int((int32) tab->ref.key_length));
for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
{
@@ -7092,24 +7089,28 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
else if (tab->type == JT_NEXT)
{
- item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name)));
- item_list.push_back(new Item_int((int32) table->key_info[tab->index].key_length));
- item_list.push_back(new Item_null());
+ KEY *key_info=table->key_info+ tab->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
+ item_list.push_back(new Item_int((int32) key_info->key_length));
+ item_list.push_back(item_null);
}
else if (tab->select && tab->select->quick)
{
- item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name)));
+ KEY *key_info=table->key_info+ tab->select->quick->index;
+ item_list.push_back(new Item_string(key_info->name,
+ strlen(key_info->name)));
item_list.push_back(new Item_int((int32) tab->select->quick->max_used_key_length));
- item_list.push_back(new Item_null());
+ item_list.push_back(item_null);
}
else
{
- item_list.push_back(new Item_null());
- item_list.push_back(new Item_null());
- item_list.push_back(new Item_null());
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
+ item_list.push_back(item_null);
}
- sprintf(bufff,"%.0f",join->best_positions[i].records_read);
- item_list.push_back(new Item_string(bufff,strlen(bufff)));
+ sprintf(buff3,"%.0f",join->best_positions[i].records_read);
+ item_list.push_back(new Item_string(buff3,strlen(buff3)));
my_bool key_read=table->key_read;
if (tab->type == JT_NEXT &&
((table->used_keys & ((key_map) 1 << tab->index))))
@@ -7177,7 +7178,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
result->send_error(0,NullS);
}
}
- if (!join->thd->lex.select->next)
+ if (!thd->lex.select->next) // Not union
{
save_lock=thd->lock;
thd->lock=(MYSQL_LOCK *)0;
@@ -7188,13 +7189,21 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
}
-static void describe_info(THD *thd, const char *info)
+static void describe_info(JOIN *join, const char *info)
{
+ THD *thd= join->thd;
+
+ if (thd->lex.select_lex.next) /* If in UNION */
+ {
+ select_describe(join,FALSE,FALSE,FALSE,info);
+ return;
+ }
List<Item> field_list;
String *packet= &thd->packet;
/* Don't log this into the slow query log */
- thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED);
+ thd->lex.select_lex.options&= ~(QUERY_NO_INDEX_USED |
+ QUERY_NO_GOOD_INDEX_USED);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1))
return; /* purecov: inspected */
diff --git a/sql/table.cc b/sql/table.cc
index 9435a83120e..2eb924caaf2 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1078,7 +1078,8 @@ bool check_db_name(const char *name)
}
}
#endif
- if (*name == '/' || *name == FN_LIBCHAR || *name == FN_EXTCHAR)
+ if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR ||
+ *name == FN_EXTCHAR)
return 1;
name++;
}