mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge mysql.com:/home/gluh/MySQL/Merge/5.0-opt
into mysql.com:/home/gluh/MySQL/Merge/5.1-opt libmysql/libmysql.c: Auto merged mysql-test/r/join_nested.result: Auto merged mysql-test/r/ps.result: Auto merged mysql-test/r/type_binary.result: Auto merged mysql-test/r/user_var.result: Auto merged mysql-test/t/ps.test: Auto merged mysql-test/t/subselect.test: Auto merged mysql-test/t/type_newdecimal.test: Auto merged mysql-test/t/user_var.test: Auto merged sql/field.h: Auto merged sql/filesort.cc: Auto merged sql/handler.cc: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_subselect.cc: Auto merged sql/item_timefunc.cc: Auto merged sql/mysql_priv.h: Auto merged sql/sql_class.h: Auto merged sql/sql_lex.cc: Auto merged sql/sql_parse.cc: Auto merged sql-common/client.c: Auto merged sql-common/my_time.c: Auto merged sql/sql_select.cc: Auto merged sql/table.cc: Auto merged strings/decimal.c: Auto merged sql/mysqld.cc: manual merge sql/sql_base.cc: manual merge
This commit is contained in:
@ -1562,3 +1562,46 @@ id ngroupbynsa
|
|||||||
2 1
|
2 1
|
||||||
2 1
|
2 1
|
||||||
DROP TABLE t1,t2,t3,t4,t5;
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
ct int DEFAULT NULL,
|
||||||
|
pc int DEFAULT NULL,
|
||||||
|
INDEX idx_ct (ct),
|
||||||
|
INDEX idx_pc (pc)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL);
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
sr int NOT NULL,
|
||||||
|
nm varchar(255) NOT NULL,
|
||||||
|
INDEX idx_sr (sr)
|
||||||
|
);
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand');
|
||||||
|
CREATE TABLE t3 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
ct int NOT NULL,
|
||||||
|
ln int NOT NULL,
|
||||||
|
INDEX idx_ct (ct),
|
||||||
|
INDEX idx_ln (ln)
|
||||||
|
);
|
||||||
|
CREATE TABLE t4 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
nm varchar(255) NOT NULL
|
||||||
|
);
|
||||||
|
INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique');
|
||||||
|
SELECT t1.*
|
||||||
|
FROM t1 LEFT JOIN
|
||||||
|
(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
|
||||||
|
WHERE t1.id='5';
|
||||||
|
id ct pc
|
||||||
|
5 NULL NULL
|
||||||
|
SELECT t1.*, t4.nm
|
||||||
|
FROM t1 LEFT JOIN
|
||||||
|
(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
|
||||||
|
LEFT JOIN t4 ON t2.sr=t4.id
|
||||||
|
WHERE t1.id='5';
|
||||||
|
id ct pc nm
|
||||||
|
5 NULL NULL NULL
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
@ -1536,6 +1536,13 @@ a
|
|||||||
1
|
1
|
||||||
2
|
2
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
|
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2 limit ?) IS NULL';
|
||||||
|
SET @arg=1;
|
||||||
|
EXECUTE stmt USING @arg;
|
||||||
|
a
|
||||||
|
1
|
||||||
|
2
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
End of 5.0 tests.
|
End of 5.0 tests.
|
||||||
create procedure proc_1() reset query cache;
|
create procedure proc_1() reset query cache;
|
||||||
|
@ -136,4 +136,13 @@ insert into t1 values(NULL, 0x412020);
|
|||||||
ERROR 22001: Data too long for column 'vb' at row 1
|
ERROR 22001: Data too long for column 'vb' at row 1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set @@sql_mode= @old_sql_mode;
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
create table t1(f1 int, f2 binary(2) not null, f3 char(2) not null);
|
||||||
|
insert into t1 set f1=1;
|
||||||
|
Warnings:
|
||||||
|
Warning 1364 Field 'f2' doesn't have a default value
|
||||||
|
Warning 1364 Field 'f3' doesn't have a default value
|
||||||
|
select hex(f2), hex(f3) from t1;
|
||||||
|
hex(f2) hex(f3)
|
||||||
|
0000
|
||||||
|
drop table t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -301,7 +301,14 @@ select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
|||||||
select @var;
|
select @var;
|
||||||
@var
|
@var
|
||||||
3
|
3
|
||||||
drop table t1;
|
create table t2 as select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
||||||
|
select * from t2;
|
||||||
|
@var:=f2
|
||||||
|
3
|
||||||
|
select @var;
|
||||||
|
@var
|
||||||
|
3
|
||||||
|
drop table t1,t2;
|
||||||
insert into city 'blah';
|
insert into city 'blah';
|
||||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''blah'' at line 1
|
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''blah'' at line 1
|
||||||
SHOW COUNT(*) WARNINGS;
|
SHOW COUNT(*) WARNINGS;
|
||||||
|
@ -994,3 +994,54 @@ SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa
|
|||||||
|
|
||||||
DROP TABLE t1,t2,t3,t4,t5;
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for bug #24345: crash with nested left outer join when outer table is substituted
|
||||||
|
# for a row that happens to have a null value for the join attribute.
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
ct int DEFAULT NULL,
|
||||||
|
pc int DEFAULT NULL,
|
||||||
|
INDEX idx_ct (ct),
|
||||||
|
INDEX idx_pc (pc)
|
||||||
|
);
|
||||||
|
INSERT INTO t1 VALUES
|
||||||
|
(1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
sr int NOT NULL,
|
||||||
|
nm varchar(255) NOT NULL,
|
||||||
|
INDEX idx_sr (sr)
|
||||||
|
);
|
||||||
|
INSERT INTO t2 VALUES
|
||||||
|
(2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand');
|
||||||
|
|
||||||
|
CREATE TABLE t3 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
ct int NOT NULL,
|
||||||
|
ln int NOT NULL,
|
||||||
|
INDEX idx_ct (ct),
|
||||||
|
INDEX idx_ln (ln)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE t4 (
|
||||||
|
id int NOT NULL PRIMARY KEY,
|
||||||
|
nm varchar(255) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique');
|
||||||
|
|
||||||
|
SELECT t1.*
|
||||||
|
FROM t1 LEFT JOIN
|
||||||
|
(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
|
||||||
|
WHERE t1.id='5';
|
||||||
|
|
||||||
|
SELECT t1.*, t4.nm
|
||||||
|
FROM t1 LEFT JOIN
|
||||||
|
(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id
|
||||||
|
LEFT JOIN t4 ON t2.sr=t4.id
|
||||||
|
WHERE t1.id='5';
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
@ -1590,8 +1590,13 @@ SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL;
|
|||||||
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL';
|
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2) IS NULL';
|
||||||
|
|
||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
|
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
PREPARE stmt FROM 'SELECT a FROM t1 WHERE (SELECT b FROM t2 limit ?) IS NULL';
|
||||||
|
SET @arg=1;
|
||||||
|
EXECUTE stmt USING @arg;
|
||||||
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--echo End of 5.0 tests.
|
||||||
|
@ -91,4 +91,12 @@ insert into t1 values(NULL, 0x412020);
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
set @@sql_mode= @old_sql_mode;
|
set @@sql_mode= @old_sql_mode;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#14171: Wrong default value for a BINARY field
|
||||||
|
#
|
||||||
|
create table t1(f1 int, f2 binary(2) not null, f3 char(2) not null);
|
||||||
|
insert into t1 set f1=1;
|
||||||
|
select hex(f2), hex(f3) from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -210,7 +210,10 @@ create table t1(f1 int, f2 int);
|
|||||||
insert into t1 values (1,2),(2,3),(3,1);
|
insert into t1 values (1,2),(2,3),(3,1);
|
||||||
select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
||||||
select @var;
|
select @var;
|
||||||
drop table t1;
|
create table t2 as select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
||||||
|
select * from t2;
|
||||||
|
select @var;
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#19024 - SHOW COUNT(*) WARNINGS not return Errors
|
# Bug#19024 - SHOW COUNT(*) WARNINGS not return Errors
|
||||||
|
@ -1096,7 +1096,8 @@ public:
|
|||||||
bool zero_pack() const { return 0; }
|
bool zero_pack() const { return 0; }
|
||||||
int reset(void)
|
int reset(void)
|
||||||
{
|
{
|
||||||
charset()->cset->fill(charset(),ptr,field_length,' ');
|
charset()->cset->fill(charset(),ptr,field_length,
|
||||||
|
(has_charset() ? ' ' : 0));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||||
|
@ -3080,7 +3080,7 @@ longlong Item_func_isnull::val_int()
|
|||||||
Handle optimization if the argument can't be null
|
Handle optimization if the argument can't be null
|
||||||
This has to be here because of the test in update_used_tables().
|
This has to be here because of the test in update_used_tables().
|
||||||
*/
|
*/
|
||||||
if (!used_tables_cache)
|
if (!used_tables_cache && !with_subselect)
|
||||||
return cached_value;
|
return cached_value;
|
||||||
return args[0]->is_null() ? 1: 0;
|
return args[0]->is_null() ? 1: 0;
|
||||||
}
|
}
|
||||||
@ -3089,7 +3089,7 @@ longlong Item_is_not_null_test::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
DBUG_ENTER("Item_is_not_null_test::val_int");
|
DBUG_ENTER("Item_is_not_null_test::val_int");
|
||||||
if (!used_tables_cache)
|
if (!used_tables_cache && !with_subselect)
|
||||||
{
|
{
|
||||||
owner->was_null|= (!cached_value);
|
owner->was_null|= (!cached_value);
|
||||||
DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
|
DBUG_PRINT("info", ("cached: %ld", (long) cached_value));
|
||||||
@ -3116,7 +3116,7 @@ void Item_is_not_null_test::update_used_tables()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
args[0]->update_used_tables();
|
args[0]->update_used_tables();
|
||||||
if (!(used_tables_cache=args[0]->used_tables()))
|
if (!(used_tables_cache=args[0]->used_tables()) && !with_subselect)
|
||||||
{
|
{
|
||||||
/* Remember if the value is always NULL or never NULL */
|
/* Remember if the value is always NULL or never NULL */
|
||||||
cached_value= (longlong) !args[0]->is_null();
|
cached_value= (longlong) !args[0]->is_null();
|
||||||
|
@ -1102,7 +1102,8 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
args[0]->update_used_tables();
|
args[0]->update_used_tables();
|
||||||
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())))
|
if ((const_item_cache= !(used_tables_cache= args[0]->used_tables())) &&
|
||||||
|
!with_subselect)
|
||||||
{
|
{
|
||||||
/* Remember if the value is always NULL or never NULL */
|
/* Remember if the value is always NULL or never NULL */
|
||||||
cached_value= (longlong) args[0]->is_null();
|
cached_value= (longlong) args[0]->is_null();
|
||||||
|
@ -4053,6 +4053,105 @@ void Item_func_set_user_var::make_field(Send_field *tmp_field)
|
|||||||
Item::make_field(tmp_field);
|
Item::make_field(tmp_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Save the value of a user variable into a field
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
save_in_field()
|
||||||
|
field target field to save the value to
|
||||||
|
no_conversion flag indicating whether conversions are allowed
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Save the function value into a field and update the user variable
|
||||||
|
accordingly. If a result field is defined and the target field doesn't
|
||||||
|
coincide with it then the value from the result field will be used as
|
||||||
|
the new value of the user variable.
|
||||||
|
|
||||||
|
The reason to have this method rather than simply using the result
|
||||||
|
field in the val_xxx() methods is that the value from the result field
|
||||||
|
not always can be used when the result field is defined.
|
||||||
|
Let's consider the following cases:
|
||||||
|
1) when filling a tmp table the result field is defined but the value of it
|
||||||
|
is undefined because it has to be produced yet. Thus we can't use it.
|
||||||
|
2) on execution of an INSERT ... SELECT statement the save_in_field()
|
||||||
|
function will be called to fill the data in the new record. If the SELECT
|
||||||
|
part uses a tmp table then the result field is defined and should be
|
||||||
|
used in order to get the correct result.
|
||||||
|
|
||||||
|
The difference between the SET_USER_VAR function and regular functions
|
||||||
|
like CONCAT is that the Item_func objects for the regular functions are
|
||||||
|
replaced by Item_field objects after the values of these functions have
|
||||||
|
been stored in a tmp table. Yet an object of the Item_field class cannot
|
||||||
|
be used to update a user variable.
|
||||||
|
Due to this we have to handle the result field in a special way here and
|
||||||
|
in the Item_func_set_user_var::send() function.
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
FALSE Ok
|
||||||
|
TRUE Error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions)
|
||||||
|
{
|
||||||
|
bool use_result_field= (result_field && result_field != field);
|
||||||
|
int error;
|
||||||
|
|
||||||
|
/* Update the value of the user variable */
|
||||||
|
check(use_result_field);
|
||||||
|
update();
|
||||||
|
|
||||||
|
if (result_type() == STRING_RESULT ||
|
||||||
|
result_type() == REAL_RESULT &&
|
||||||
|
field->result_type() == STRING_RESULT)
|
||||||
|
{
|
||||||
|
String *result;
|
||||||
|
CHARSET_INFO *cs= collation.collation;
|
||||||
|
char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
|
||||||
|
str_value.set_quick(buff, sizeof(buff), cs);
|
||||||
|
result= entry->val_str(&null_value, &str_value, decimals);
|
||||||
|
|
||||||
|
if (null_value)
|
||||||
|
{
|
||||||
|
str_value.set_quick(0, 0, cs);
|
||||||
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: If null_value == FALSE, "result" must be not NULL. */
|
||||||
|
|
||||||
|
field->set_notnull();
|
||||||
|
error=field->store(result->ptr(),result->length(),cs);
|
||||||
|
str_value.set_quick(0, 0, cs);
|
||||||
|
}
|
||||||
|
else if (result_type() == REAL_RESULT)
|
||||||
|
{
|
||||||
|
double nr= entry->val_real(&null_value);
|
||||||
|
if (null_value)
|
||||||
|
return set_field_to_null(field);
|
||||||
|
field->set_notnull();
|
||||||
|
error=field->store(nr);
|
||||||
|
}
|
||||||
|
else if (result_type() == DECIMAL_RESULT)
|
||||||
|
{
|
||||||
|
my_decimal decimal_value;
|
||||||
|
my_decimal *value= entry->val_decimal(&null_value, &decimal_value);
|
||||||
|
if (null_value)
|
||||||
|
return set_field_to_null(field);
|
||||||
|
field->set_notnull();
|
||||||
|
error=field->store_decimal(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
longlong nr= entry->val_int(&null_value);
|
||||||
|
if (null_value)
|
||||||
|
return set_field_to_null_with_conversions(field, no_conversions);
|
||||||
|
field->set_notnull();
|
||||||
|
error=field->store(nr, unsigned_flag);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *
|
String *
|
||||||
Item_func_get_user_var::val_str(String *str)
|
Item_func_get_user_var::val_str(String *str)
|
||||||
{
|
{
|
||||||
|
@ -1214,6 +1214,7 @@ public:
|
|||||||
void print(String *str);
|
void print(String *str);
|
||||||
void print_as_stmt(String *str);
|
void print_as_stmt(String *str);
|
||||||
const char *func_name() const { return "set_user_var"; }
|
const char *func_name() const { return "set_user_var"; }
|
||||||
|
int save_in_field(Field *field, bool no_conversions);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1478,6 +1478,7 @@ File open_binlog(IO_CACHE *log, const char *log_file_name,
|
|||||||
/* mysqld.cc */
|
/* mysqld.cc */
|
||||||
extern void MYSQLerror(const char*);
|
extern void MYSQLerror(const char*);
|
||||||
void refresh_status(THD *thd);
|
void refresh_status(THD *thd);
|
||||||
|
my_bool mysql_rm_tmp_tables(void);
|
||||||
|
|
||||||
/* item_func.cc */
|
/* item_func.cc */
|
||||||
extern bool check_reserved_words(LEX_STRING *name);
|
extern bool check_reserved_words(LEX_STRING *name);
|
||||||
|
@ -3637,7 +3637,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
|
|||||||
error_handler_hook= my_message_sql;
|
error_handler_hook= my_message_sql;
|
||||||
start_signal_handler(); // Creates pidfile
|
start_signal_handler(); // Creates pidfile
|
||||||
|
|
||||||
if (acl_init(opt_noacl) ||
|
if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
|
||||||
my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
|
my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
|
||||||
{
|
{
|
||||||
abort_loop=1;
|
abort_loop=1;
|
||||||
|
@ -40,7 +40,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list,
|
|||||||
char *cache_key, uint cache_key_length,
|
char *cache_key, uint cache_key_length,
|
||||||
MEM_ROOT *mem_root, uint flags);
|
MEM_ROOT *mem_root, uint flags);
|
||||||
static void free_cache_entry(TABLE *entry);
|
static void free_cache_entry(TABLE *entry);
|
||||||
static void mysql_rm_tmp_tables(void);
|
|
||||||
static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
|
static bool open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
|
||||||
uint db_stat, uint prgflag,
|
uint db_stat, uint prgflag,
|
||||||
uint ha_open_flags, TABLE *outparam,
|
uint ha_open_flags, TABLE *outparam,
|
||||||
@ -63,7 +62,6 @@ extern "C" byte *table_cache_key(const byte *record,uint *length,
|
|||||||
|
|
||||||
bool table_cache_init(void)
|
bool table_cache_init(void)
|
||||||
{
|
{
|
||||||
mysql_rm_tmp_tables();
|
|
||||||
return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
|
return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
|
||||||
0, 0,table_cache_key,
|
0, 0,table_cache_key,
|
||||||
(hash_free_key) free_cache_entry, 0) != 0;
|
(hash_free_key) free_cache_entry, 0) != 0;
|
||||||
@ -6072,14 +6070,21 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mysql_rm_tmp_tables(void)
|
my_bool mysql_rm_tmp_tables(void)
|
||||||
{
|
{
|
||||||
uint i, idx;
|
uint i, idx;
|
||||||
char filePath[FN_REFLEN], *tmpdir;
|
char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
|
||||||
MY_DIR *dirp;
|
MY_DIR *dirp;
|
||||||
FILEINFO *file;
|
FILEINFO *file;
|
||||||
|
TABLE tmp_table;
|
||||||
|
THD *thd;
|
||||||
DBUG_ENTER("mysql_rm_tmp_tables");
|
DBUG_ENTER("mysql_rm_tmp_tables");
|
||||||
|
|
||||||
|
if (!(thd= new THD))
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
thd->thread_stack= (char*) &thd;
|
||||||
|
thd->store_globals();
|
||||||
|
|
||||||
for (i=0; i<=mysql_tmpdir_list.max; i++)
|
for (i=0; i<=mysql_tmpdir_list.max; i++)
|
||||||
{
|
{
|
||||||
tmpdir=mysql_tmpdir_list.list[i];
|
tmpdir=mysql_tmpdir_list.list[i];
|
||||||
@ -6098,15 +6103,39 @@ static void mysql_rm_tmp_tables(void)
|
|||||||
(file->name[1] == '.' && !file->name[2])))
|
(file->name[1] == '.' && !file->name[2])))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
|
if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
|
||||||
|
{
|
||||||
|
char *ext= fn_ext(file->name);
|
||||||
|
uint ext_len= strlen(ext);
|
||||||
|
uint filePath_len= my_snprintf(filePath, sizeof(filePath),
|
||||||
|
"%s%c%s", FN_LIBCHAR,tmpdir,
|
||||||
|
file->name);
|
||||||
|
if (!bcmp(reg_ext, ext, ext_len))
|
||||||
{
|
{
|
||||||
sprintf(filePath,"%s%c%s",tmpdir,FN_LIBCHAR,file->name);
|
TABLE tmp_table;
|
||||||
VOID(my_delete(filePath,MYF(MY_WME)));
|
if (!openfrm(thd, filePath, "tmp_table", (uint) 0,
|
||||||
|
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
|
||||||
|
0, &tmp_table))
|
||||||
|
{
|
||||||
|
/* We should cut file extention before deleting of table */
|
||||||
|
memcpy(filePathCopy, filePath, filePath_len - ext_len);
|
||||||
|
filePathCopy[filePath_len - ext_len]= 0;
|
||||||
|
tmp_table.file->delete_table(filePathCopy);
|
||||||
|
closefrm(&tmp_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
File can be already deleted by tmp_table.file->delete_table().
|
||||||
|
So we hide error messages which happnes during deleting of these
|
||||||
|
files(MYF(0)).
|
||||||
|
*/
|
||||||
|
VOID(my_delete(filePath, MYF(0)));
|
||||||
}
|
}
|
||||||
my_dirend(dirp);
|
my_dirend(dirp);
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
delete thd;
|
||||||
|
my_pthread_setspecific_ptr(THR_THD, 0);
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1934,6 +1934,7 @@ void st_select_lex_unit::set_limit(SELECT_LEX *sl)
|
|||||||
{
|
{
|
||||||
ha_rows select_limit_val;
|
ha_rows select_limit_val;
|
||||||
|
|
||||||
|
DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
|
||||||
select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() :
|
select_limit_val= (ha_rows)(sl->select_limit ? sl->select_limit->val_uint() :
|
||||||
HA_POS_ERROR);
|
HA_POS_ERROR);
|
||||||
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
|
offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
|
||||||
|
@ -2333,8 +2333,18 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
|
|||||||
substitution of a const table the key value happens to be null
|
substitution of a const table the key value happens to be null
|
||||||
then we can state that there are no matches for this equi-join.
|
then we can state that there are no matches for this equi-join.
|
||||||
*/
|
*/
|
||||||
if ((keyuse= s->keyuse) && *s->on_expr_ref)
|
if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
When performing an outer join operation if there are no matching rows
|
||||||
|
for the single row of the outer table all the inner tables are to be
|
||||||
|
null complemented and thus considered as constant tables.
|
||||||
|
Here we apply this consideration to the case of outer join operations
|
||||||
|
with a single inner table only because the case with nested tables
|
||||||
|
would require a more thorough analysis.
|
||||||
|
TODO. Apply single row substitution to null complemented inner tables
|
||||||
|
for nested outer join operations.
|
||||||
|
*/
|
||||||
while (keyuse->table == table)
|
while (keyuse->table == table)
|
||||||
{
|
{
|
||||||
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
|
if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
|
||||||
|
Reference in New Issue
Block a user