mirror of
https://github.com/MariaDB/server.git
synced 2025-06-23 19:21:55 +03:00
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-explain-4.1 mysql-test/r/subselect.result: Auto merged mysql-test/t/subselect.test: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_union.cc: Auto merged
This commit is contained in:
@ -18,15 +18,15 @@ extern ulint ut_total_allocated_memory;
|
||||
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ut_memcpy(void* dest, void* sour, ulint n);
|
||||
ut_memcpy(void* dest, const void* sour, ulint n);
|
||||
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ut_memmove(void* dest, void* sour, ulint n);
|
||||
ut_memmove(void* dest, const void* sour, ulint n);
|
||||
|
||||
UNIV_INLINE
|
||||
int
|
||||
ut_memcmp(void* str1, void* str2, ulint n);
|
||||
ut_memcmp(const void* str1, const void* str2, ulint n);
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
@ -75,7 +75,7 @@ ut_free_all_mem(void);
|
||||
|
||||
UNIV_INLINE
|
||||
char*
|
||||
ut_strcpy(char* dest, char* sour);
|
||||
ut_strcpy(char* dest, const char* sour);
|
||||
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
@ -83,7 +83,7 @@ ut_strlen(const char* str);
|
||||
|
||||
UNIV_INLINE
|
||||
int
|
||||
ut_strcmp(void* str1, void* str2);
|
||||
ut_strcmp(const void* str1, const void* str2);
|
||||
|
||||
/**************************************************************************
|
||||
Determine the length of a string when it is quoted with ut_strcpyq(). */
|
||||
@ -118,17 +118,6 @@ ut_memcpyq(
|
||||
const char* src, /* in: string to be quoted */
|
||||
ulint len); /* in: length of src */
|
||||
|
||||
/**************************************************************************
|
||||
Catenates two strings into newly allocated memory. The memory must be freed
|
||||
using mem_free. */
|
||||
|
||||
char*
|
||||
ut_str_catenate(
|
||||
/*============*/
|
||||
/* out, own: catenated null-terminated string */
|
||||
char* str1, /* in: null-terminated string */
|
||||
char* str2); /* in: null-terminated string */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "ut0mem.ic"
|
||||
#endif
|
||||
|
@ -8,28 +8,28 @@ Created 5/30/1994 Heikki Tuuri
|
||||
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ut_memcpy(void* dest, void* sour, ulint n)
|
||||
ut_memcpy(void* dest, const void* sour, ulint n)
|
||||
{
|
||||
return(memcpy(dest, sour, n));
|
||||
}
|
||||
|
||||
UNIV_INLINE
|
||||
void*
|
||||
ut_memmove(void* dest, void* sour, ulint n)
|
||||
ut_memmove(void* dest, const void* sour, ulint n)
|
||||
{
|
||||
return(memmove(dest, sour, n));
|
||||
}
|
||||
|
||||
UNIV_INLINE
|
||||
int
|
||||
ut_memcmp(void* str1, void* str2, ulint n)
|
||||
ut_memcmp(const void* str1, const void* str2, ulint n)
|
||||
{
|
||||
return(memcmp(str1, str2, n));
|
||||
}
|
||||
|
||||
UNIV_INLINE
|
||||
char*
|
||||
ut_strcpy(char* dest, char* sour)
|
||||
ut_strcpy(char* dest, const char* sour)
|
||||
{
|
||||
return(strcpy(dest, sour));
|
||||
}
|
||||
@ -43,9 +43,9 @@ ut_strlen(const char* str)
|
||||
|
||||
UNIV_INLINE
|
||||
int
|
||||
ut_strcmp(void* str1, void* str2)
|
||||
ut_strcmp(const void* str1, const void* str2)
|
||||
{
|
||||
return(strcmp((char*)str1, (char*)str2));
|
||||
return(strcmp((const char*)str1, (const char*)str2));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -369,7 +369,16 @@ os_file_handle_error(
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
#if !defined(__WIN__) && !defined(UNIV_HOTBACKUP)
|
||||
#undef USE_FILE_LOCK
|
||||
#define USE_FILE_LOCK
|
||||
#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__)
|
||||
/* InnoDB Hot Backup does not lock the data files.
|
||||
* On Windows, mandatory locking is used.
|
||||
* On FreeBSD with LinuxThreads, advisory locking does not work properly.
|
||||
*/
|
||||
# undef USE_FILE_LOCK
|
||||
#endif
|
||||
#ifdef USE_FILE_LOCK
|
||||
/********************************************************************
|
||||
Obtain an exclusive lock on a file. */
|
||||
static
|
||||
@ -393,7 +402,7 @@ os_file_lock(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* !defined(__WIN__) && !defined(UNIV_HOTBACKUP) */
|
||||
#endif /* USE_FILE_LOCK */
|
||||
|
||||
/********************************************************************
|
||||
Does error handling when a file operation fails. */
|
||||
@ -852,7 +861,7 @@ try_again:
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
}
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
#ifdef USE_FILE_LOCK
|
||||
} else if (os_file_lock(file, name)) {
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
@ -961,7 +970,7 @@ os_file_create_simple_no_error_handling(
|
||||
|
||||
if (file == -1) {
|
||||
*success = FALSE;
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
#ifdef USE_FILE_LOCK
|
||||
} else if (os_file_lock(file, name)) {
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
@ -1172,7 +1181,7 @@ try_again:
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
}
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
#ifdef USE_FILE_LOCK
|
||||
} else if (os_file_lock(file, name)) {
|
||||
*success = FALSE;
|
||||
file = -1;
|
||||
|
@ -273,29 +273,3 @@ ut_memcpyq(
|
||||
|
||||
return(dest);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Catenates two strings into newly allocated memory. The memory must be freed
|
||||
using mem_free. */
|
||||
|
||||
char*
|
||||
ut_str_catenate(
|
||||
/*============*/
|
||||
/* out, own: catenated null-terminated string */
|
||||
char* str1, /* in: null-terminated string */
|
||||
char* str2) /* in: null-terminated string */
|
||||
{
|
||||
ulint len1;
|
||||
ulint len2;
|
||||
char* str;
|
||||
|
||||
len1 = ut_strlen(str1);
|
||||
len2 = ut_strlen(str2);
|
||||
|
||||
str = mem_alloc(len1 + len2 + 1);
|
||||
|
||||
ut_memcpy(str, str1, len1);
|
||||
ut_memcpy(str + len1, str2, len2 + 1);
|
||||
|
||||
return(str);
|
||||
}
|
||||
|
@ -1728,3 +1728,92 @@ SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t
|
||||
id c
|
||||
1 1
|
||||
2 0
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 ( a int, b int );
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
3
|
||||
SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
3
|
||||
SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
3
|
||||
SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
3
|
||||
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
3
|
||||
ALTER TABLE t1 ADD INDEX (a);
|
||||
SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
3
|
||||
SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
3
|
||||
SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
3
|
||||
SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
3
|
||||
SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
2
|
||||
3
|
||||
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
2
|
||||
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
a
|
||||
1
|
||||
3
|
||||
DROP TABLE t1;
|
||||
|
@ -1125,4 +1125,36 @@ INSERT INTO t1 VALUES (1), (2);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
|
||||
SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
|
||||
DROP TABLE t1,t2
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# ALL/ANY test
|
||||
#
|
||||
CREATE TABLE t1 ( a int, b int );
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
|
||||
SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
ALTER TABLE t1 ADD INDEX (a);
|
||||
SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
|
||||
DROP TABLE t1;
|
||||
|
@ -56,10 +56,24 @@ void Item_subselect::init(st_select_lex *select_lex,
|
||||
DBUG_PRINT("subs", ("select_lex 0x%xl", (ulong) select_lex));
|
||||
unit= select_lex->master_unit();
|
||||
|
||||
if (select_lex->next_select())
|
||||
engine= new subselect_union_engine(unit, result, this);
|
||||
if (unit->item)
|
||||
{
|
||||
/*
|
||||
Item can be changed in JOIN::prepare while engine in JOIN::optimize
|
||||
=> we do not copy old_engine here
|
||||
*/
|
||||
engine= unit->item->engine;
|
||||
unit->item->engine= 0;
|
||||
unit->item= this;
|
||||
engine->change_item(this, result);
|
||||
}
|
||||
else
|
||||
engine= new subselect_single_select_engine(select_lex, result, this);
|
||||
{
|
||||
if (select_lex->next_select())
|
||||
engine= new subselect_union_engine(unit, result, this);
|
||||
else
|
||||
engine= new subselect_single_select_engine(select_lex, result, this);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -69,11 +83,13 @@ void Item_subselect::cleanup()
|
||||
Item_result_field::cleanup();
|
||||
if (old_engine)
|
||||
{
|
||||
engine->cleanup();
|
||||
if (engine)
|
||||
engine->cleanup();
|
||||
engine= old_engine;
|
||||
old_engine= 0;
|
||||
}
|
||||
engine->cleanup();
|
||||
if (engine)
|
||||
engine->cleanup();
|
||||
reset();
|
||||
value_assigned= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
@ -127,7 +143,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
|
||||
if (have_to_be_excluded)
|
||||
engine->exclude();
|
||||
substitution= 0;
|
||||
fixed= 1;
|
||||
thd->where= "checking transformed subquery";
|
||||
if (!(*ref)->fixed)
|
||||
ret= (*ref)->fix_fields(thd, tables, ref);
|
||||
@ -660,10 +675,20 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
item= new Item_sum_min(*select_lex->ref_pointer_array);
|
||||
}
|
||||
*select_lex->ref_pointer_array= item;
|
||||
select_lex->item_list.empty();
|
||||
select_lex->item_list.push_back(item);
|
||||
{
|
||||
List_iterator<Item> it(select_lex->item_list);
|
||||
it++;
|
||||
it.replace(item);
|
||||
}
|
||||
|
||||
// fix_fields call for 'item' will be made during new subquery fix_fields
|
||||
/*
|
||||
Item_sum_(max|min) can't substitute other item => we can use 0 as
|
||||
reference
|
||||
*/
|
||||
if (item->fix_fields(thd, join->tables_list, 0))
|
||||
goto err;
|
||||
/* we added aggregate function => we have to change statistic */
|
||||
count_field_types(&join->tmp_table_param, join->all_fields, 0);
|
||||
|
||||
subs= new Item_singlerow_subselect(select_lex);
|
||||
}
|
||||
@ -1428,3 +1453,67 @@ void subselect_indexsubquery_engine::print(String *str)
|
||||
}
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
change select_result object of engine
|
||||
|
||||
SINOPSYS
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
|
||||
RETURN
|
||||
0 OK
|
||||
-1 error
|
||||
*/
|
||||
|
||||
int subselect_single_select_engine::change_item(Item_subselect *si,
|
||||
select_subselect *res)
|
||||
{
|
||||
item= si;
|
||||
result= res;
|
||||
return select_lex->join->change_result(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
change select_result object of engine
|
||||
|
||||
SINOPSYS
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
|
||||
RETURN
|
||||
0 OK
|
||||
-1 error
|
||||
*/
|
||||
|
||||
int subselect_union_engine::change_item(Item_subselect *si,
|
||||
select_subselect *res)
|
||||
{
|
||||
item= si;
|
||||
int rc= unit->change_result(res, result);
|
||||
result= res;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
change select_result emulation, never should be called
|
||||
|
||||
SINOPSYS
|
||||
subselect_single_select_engine::change_result()
|
||||
si new subselect Item
|
||||
res new select_result object
|
||||
|
||||
RETURN
|
||||
-1 error
|
||||
*/
|
||||
|
||||
int subselect_uniquesubquery_engine::change_item(Item_subselect *si,
|
||||
select_subselect *res)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
return -1;
|
||||
}
|
||||
|
@ -290,6 +290,7 @@ public:
|
||||
virtual table_map upper_select_const_tables()= 0;
|
||||
static table_map calc_const_tables(TABLE_LIST *);
|
||||
virtual void print(String *str)= 0;
|
||||
virtual int change_item(Item_subselect *si, select_subselect *result)= 0;
|
||||
};
|
||||
|
||||
|
||||
@ -313,6 +314,7 @@ public:
|
||||
void exclude();
|
||||
table_map upper_select_const_tables();
|
||||
void print (String *str);
|
||||
int change_item(Item_subselect *si, select_subselect *result);
|
||||
};
|
||||
|
||||
|
||||
@ -332,6 +334,7 @@ public:
|
||||
void exclude();
|
||||
table_map upper_select_const_tables();
|
||||
void print (String *str);
|
||||
int change_item(Item_subselect *si, select_subselect *result);
|
||||
};
|
||||
|
||||
|
||||
@ -360,6 +363,7 @@ public:
|
||||
void exclude();
|
||||
table_map upper_select_const_tables() { return 0; }
|
||||
void print (String *str);
|
||||
int change_item(Item_subselect *si, select_subselect *result);
|
||||
};
|
||||
|
||||
|
||||
|
@ -502,6 +502,14 @@ void Item_sum_variance::update_field()
|
||||
|
||||
/* min & max */
|
||||
|
||||
void Item_sum_hybrid::clear()
|
||||
{
|
||||
sum= 0.0;
|
||||
sum_int= 0;
|
||||
value.length(0);
|
||||
null_value= 1;
|
||||
}
|
||||
|
||||
double Item_sum_hybrid::val()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
@ -415,13 +415,7 @@ class Item_sum_hybrid :public Item_sum
|
||||
table_map used_tables() const { return used_table_cache; }
|
||||
bool const_item() const { return !used_table_cache; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
sum=0.0;
|
||||
sum_int=0;
|
||||
value.length(0);
|
||||
null_value=1;
|
||||
}
|
||||
void clear();
|
||||
double val();
|
||||
longlong val_int();
|
||||
void reset_field();
|
||||
|
@ -1711,6 +1711,7 @@ TABLE_LIST *st_lex::link_first_table_back(TABLE_LIST *tables,
|
||||
st_select_lex::print is in sql_select.h
|
||||
|
||||
st_select_lex_unit::prepare, st_select_lex_unit::exec,
|
||||
st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism
|
||||
st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,
|
||||
st_select_lex_unit::change_result
|
||||
are in sql_union.cc
|
||||
*/
|
||||
|
@ -372,6 +372,7 @@ public:
|
||||
void print(String *str);
|
||||
|
||||
ulong init_prepare_fake_select_lex(THD *thd);
|
||||
int change_result(select_subselect *result, select_subselect *old_result);
|
||||
|
||||
friend void mysql_init_query(THD *thd);
|
||||
friend int subselect_union_engine::exec();
|
||||
|
@ -1585,8 +1585,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
|
||||
{
|
||||
//here is EXPLAIN of subselect or derived table
|
||||
join->result= result;
|
||||
if (!join->procedure && result->prepare(join->fields_list, unit))
|
||||
if (join->change_result(result))
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
@ -9563,3 +9562,27 @@ void st_select_lex::print(THD *thd, String *str)
|
||||
|
||||
// PROCEDURE unsupported here
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
change select_result object of JOIN
|
||||
|
||||
SYNOPSIS
|
||||
JOIN::change_result()
|
||||
res new select_result object
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - error
|
||||
*/
|
||||
|
||||
int JOIN::change_result(select_result *res)
|
||||
{
|
||||
DBUG_ENTER("JOIN::change_result");
|
||||
result= res;
|
||||
if (!procedure && result->prepare(fields_list, select_lex->master_unit()))
|
||||
{
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -304,6 +304,7 @@ class JOIN :public Sql_alloc
|
||||
return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
|
||||
!group_list);
|
||||
}
|
||||
int change_result(select_result *result);
|
||||
};
|
||||
|
||||
|
||||
|
@ -577,3 +577,32 @@ void st_select_lex_unit::reinit_exec_mechanism()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
change select_result object of unit
|
||||
|
||||
SYNOPSIS
|
||||
st_select_lex_unit::change_result()
|
||||
result new select_result object
|
||||
old_result old select_result object
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - error
|
||||
*/
|
||||
|
||||
int st_select_lex_unit::change_result(select_subselect *result,
|
||||
select_subselect *old_result)
|
||||
{
|
||||
int res= 0;
|
||||
for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
|
||||
{
|
||||
if (sl->join && sl->join->result == old_result)
|
||||
if ((res= sl->join->change_result(result)))
|
||||
return (res);
|
||||
}
|
||||
if (fake_select_lex && fake_select_lex->join)
|
||||
res= fake_select_lex->join->change_result(result);
|
||||
return (res);
|
||||
}
|
||||
|
Reference in New Issue
Block a user