Commit e077890b authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

simple subselects ported to new select_lex structures

parent 4cb3760b
...@@ -243,4 +243,6 @@ ...@@ -243,4 +243,6 @@
#define ER_MIXING_NOT_ALLOWED 1224 #define ER_MIXING_NOT_ALLOWED 1224
#define ER_DUP_ARGUMENT 1225 #define ER_DUP_ARGUMENT 1225
#define ER_USER_LIMIT_REACHED 1226 #define ER_USER_LIMIT_REACHED 1226
#define ER_ERROR_MESSAGES 227 #define ER_SUBSELECT_NO_1_COL 1227
#define ER_SUBSELECT_NO_1_ROW 1228
#define ER_ERROR_MESSAGES 229
...@@ -43,7 +43,8 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \ ...@@ -43,7 +43,8 @@ sqlsources = convert.cc derror.cc field.cc field_conv.cc filesort.cc \
hostname.cc init.cc \ hostname.cc init.cc \
item.cc item_buff.cc item_cmpfunc.cc item_create.cc \ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
item_uniq.cc key.cc lock.cc log.cc log_event.cc mf_iocache.cc\ item_uniq.cc item_subselect.cc \
key.cc lock.cc log.cc log_event.cc mf_iocache.cc\
mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \ mini_client.cc net_pkg.cc net_serv.cc opt_ft.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \ opt_sum.cc procedure.cc records.cc sql_acl.cc \
repl_failsafe.cc slave.cc \ repl_failsafe.cc slave.cc \
......
drop table if exists t1,t2,t3,t4;
create table t1 (a int);
create table t2 (a int, b int);
create table t3 (a int);
create table t4 (a int, b int);
insert into t1 values (2);
insert into t2 values (1,7),(2,7);
insert into t4 values (4,8),(3,8),(5,9);
select (select a from t1), a from t2;
(select a from t1) a
2 1
2 2
select (select a from t3), a from t2;
(select a from t3) a
NULL 1
NULL 2
select * from t2 where t2.a=(select a from t1);
a b
2 7
insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 limit 1);
a b
1 7
2 7
select * from t2 where t2.b=(select a from t3 order by 1 limit 1)
union (select * from t4 order by a limit 2) limit 3;
a b
1 7
2 7
3 8
drop table t1,t2,t3,t4;
#select (select 2);
drop table if exists t1,t2,t3,t4;
create table t1 (a int);
create table t2 (a int, b int);
create table t3 (a int);
create table t4 (a int, b int);
insert into t1 values (2);
insert into t2 values (1,7),(2,7);
insert into t4 values (4,8),(3,8),(5,9);
select (select a from t1), a from t2;
select (select a from t3), a from t2;
select * from t2 where t2.a=(select a from t1);
insert into t3 values (6),(7),(3);
select * from t2 where t2.b=(select a from t3 order by 1 limit 1);
select * from t2 where t2.b=(select a from t3 order by 1 limit 1)
union (select * from t4 order by a limit 2) limit 3;
drop table t1,t2,t3,t4;
...@@ -46,7 +46,7 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ ...@@ -46,7 +46,7 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
item_strfunc.h item_timefunc.h item_uniq.h \ item_strfunc.h item_timefunc.h item_uniq.h \
item_create.h mysql_priv.h \ item_create.h item_subselect.h mysql_priv.h \
procedure.h sql_class.h sql_lex.h sql_list.h \ procedure.h sql_class.h sql_lex.h sql_list.h \
sql_manager.h sql_map.h sql_string.h unireg.h \ sql_manager.h sql_map.h sql_string.h unireg.h \
field.h handler.h \ field.h handler.h \
...@@ -60,7 +60,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -60,7 +60,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
mysqld_SOURCES = sql_lex.cc sql_handler.cc \ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
item.cc item_sum.cc item_buff.cc item_func.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \
item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
thr_malloc.cc item_create.cc \ thr_malloc.cc item_create.cc item_subselect.cc\
field.cc key.cc sql_class.cc sql_list.cc \ field.cc key.cc sql_class.cc sql_list.cc \
net_serv.cc net_pkg.cc lock.cc my_lock.c \ net_serv.cc net_pkg.cc lock.cc my_lock.c \
sql_string.cc sql_manager.cc sql_map.cc \ sql_string.cc sql_manager.cc sql_map.cc \
......
...@@ -32,7 +32,8 @@ public: ...@@ -32,7 +32,8 @@ public:
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM, enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM, INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_ITEM,
COPY_STR_ITEM,FIELD_AVG_ITEM, COPY_STR_ITEM,FIELD_AVG_ITEM,
PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM}; PROC_ITEM,COND_ITEM,REF_ITEM,FIELD_STD_ITEM, CONST_ITEM,
SUBSELECT_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
String str_value; /* used to store value */ String str_value; /* used to store value */
...@@ -46,7 +47,6 @@ public: ...@@ -46,7 +47,6 @@ public:
my_bool unsigned_flag; my_bool unsigned_flag;
my_bool with_sum_func; my_bool with_sum_func;
// alloc & destruct is done as start of select using sql_alloc // alloc & destruct is done as start of select using sql_alloc
Item(); Item();
virtual ~Item() { name=0; } /*lint -e1509 */ virtual ~Item() { name=0; } /*lint -e1509 */
...@@ -371,6 +371,7 @@ public: ...@@ -371,6 +371,7 @@ public:
#include "item_strfunc.h" #include "item_strfunc.h"
#include "item_timefunc.h" #include "item_timefunc.h"
#include "item_uniq.h" #include "item_uniq.h"
#include "item_subselect.h"
class Item_copy_string :public Item class Item_copy_string :public Item
{ {
...@@ -458,3 +459,4 @@ extern Item_result item_cmp_type(Item_result a,Item_result b); ...@@ -458,3 +459,4 @@ extern Item_result item_cmp_type(Item_result a,Item_result b);
extern Item *resolve_const_item(Item *item,Item *cmp_item); extern Item *resolve_const_item(Item *item,Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item); extern bool field_is_equal_to_item(Field *field,Item *item);
Item *get_system_var(LEX_STRING name); Item *get_system_var(LEX_STRING name);
...@@ -38,7 +38,9 @@ public: ...@@ -38,7 +38,9 @@ public:
Field *tmp_table_field(TABLE *t_arg) Field *tmp_table_field(TABLE *t_arg)
{ {
if (!t_arg) return result_field; if (!t_arg) return result_field;
return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); return (max_length > 255) ?
(Field *) new Field_blob(max_length,maybe_null, name,t_arg, binary) :
(Field *) new Field_string(max_length,maybe_null, name,t_arg, binary);
} }
}; };
......
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
subselect Item
SUBSELECT TODO:
- add function from mysql_select that use JOIN* as parameter to JOIN methods
(sql_select.h/sql_select.cc)
- remove double 'having' & 'having_list' from JOIN
(sql_select.h/sql_select.cc)
- add subselect union select (sql_union.cc)
- depended from outer select subselects
*/
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
#endif
#include "mysql_priv.h"
#include "sql_select.h"
Item_subselect::Item_subselect(THD *thd, st_select_lex *select_lex):
executed(0)
{
DBUG_ENTER("Item_subselect::Item_subselect");
DBUG_PRINT("subs", ("select_lex 0x%xl", (long) select_lex));
result= new select_subselect(this);
join= new JOIN(thd, select_lex->item_list, select_lex->options, result);
this->select_lex= select_lex;
maybe_null= 1;
/*
item value is NULL if select_subselect not changed this value
(i.e. some rows will be found returned)
*/
assign_null();
DBUG_VOID_RETURN;
}
Item::Type Item_subselect::type() const
{
return SUBSELECT_ITEM;
}
double Item_subselect::val ()
{
if (exec())
return 0;
return real_value;
}
longlong Item_subselect::val_int ()
{
if (exec())
return 0;
return int_value;
}
String *Item_subselect::val_str (String *str)
{
if (exec() || null_value)
return 0;
return &str_value;
}
void Item_subselect::make_field (Send_field *tmp_field)
{
if (null_value)
{
init_make_field(tmp_field,FIELD_TYPE_NULL);
tmp_field->length=4;
} else {
init_make_field(tmp_field, ((result_type() == STRING_RESULT) ?
FIELD_TYPE_VAR_STRING :
(result_type() == INT_RESULT) ?
FIELD_TYPE_LONGLONG : FIELD_TYPE_DOUBLE));
}
}
bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables)
{
// Is it one field subselect?
if (select_lex->item_list.elements != 1)
{
my_printf_error(ER_SUBSELECT_NO_1_COL, ER(ER_SUBSELECT_NO_1_COL), MYF(0));
return 1;
}
SELECT_LEX *save_select= thd->lex.select;
thd->lex.select= select_lex;
if(join->prepare((TABLE_LIST*) select_lex->table_list.first,
select_lex->where,
(ORDER*) select_lex->order_list.first,
(ORDER*) select_lex->group_list.first,
select_lex->having,
(ORDER*) 0, select_lex,
(SELECT_LEX_UNIT*) select_lex->master))
return 1;
if (join->optimize())
{
executed= 1;
return 1;
}
thd->lex.select= save_select;
return 0;
}
int Item_subselect::exec()
{
if (!executed)
{
SELECT_LEX *save_select= join->thd->lex.select;
join->thd->lex.select= select_lex;
join->exec();
join->thd->lex.select= save_select;
if (!executed)
//No rows returned => value is null (returned as inited)
executed= 1;
return join->error;
}
return 0;
}
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* subselect Item */
#ifdef __GNUC__
#pragma interface /* gcc class implementation */
#endif
struct st_select_lex;
class JOIN;
class select_subselect;
/* simple (not depended of covered select ) subselect */
class Item_subselect :public Item
{
protected:
my_bool executed; /* simple subselect is executed */
longlong int_value;
double real_value;
enum Item_result res_type;
int exec();
void assign_null()
{
null_value= 1;
int_value= 0;
real_value= 0;
max_length= 4;
res_type= STRING_RESULT;
}
public:
st_select_lex *select_lex;
JOIN *join;
select_subselect *result;
Item_subselect(THD *thd, st_select_lex *select_lex);
Item_subselect(Item_subselect *item)
{
null_value= item->null_value;
int_value= item->int_value;
real_value= item->real_value;
max_length= item->max_length;
decimals= item->decimals;
res_type= item->res_type;
executed= item->executed;
select_lex= item->select_lex;
join= item->join;
result= item->result;
name= item->name;
}
enum Type type() const;
double val ();
longlong val_int ();
String *val_str (String *);
bool is_null() { return null_value; }
void make_field (Send_field *);
bool fix_fields(THD *thd, TABLE_LIST *tables);
Item *new_item() { return new Item_subselect(this); }
enum Item_result result_type() const { return res_type; }
friend class select_subselect;
};
...@@ -237,3 +237,5 @@ ...@@ -237,3 +237,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -231,3 +231,5 @@ ...@@ -231,3 +231,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -236,3 +236,5 @@ ...@@ -236,3 +236,5 @@
"Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.", "Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.",
"Optie '%s' tweemaal gebruikt in opdracht", "Optie '%s' tweemaal gebruikt in opdracht",
"Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)", "Gebruiker '%-64s' heeft het maximale gebruik van de '%s' faciliteit overschreden (huidige waarde: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -233,3 +233,5 @@ ...@@ -233,3 +233,5 @@
"Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud", "Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud",
"Mrangut '%s' on lauses kasutatud topelt", "Mrangut '%s' on lauses kasutatud topelt",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -231,3 +231,5 @@ ...@@ -231,3 +231,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -230,3 +230,5 @@ ...@@ -230,3 +230,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -230,3 +230,5 @@ ...@@ -230,3 +230,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -230,3 +230,5 @@ ...@@ -230,3 +230,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -230,3 +230,5 @@ ...@@ -230,3 +230,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -232,3 +232,5 @@ ...@@ -232,3 +232,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -232,3 +232,5 @@ ...@@ -232,3 +232,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -231,3 +231,5 @@ ...@@ -231,3 +231,5 @@
" transactional non-transactional ", " transactional non-transactional ",
" '%s' ", " '%s' ",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
" ",
" ",
...@@ -236,3 +236,5 @@ ...@@ -236,3 +236,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -229,3 +229,5 @@ ...@@ -229,3 +229,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -228,3 +228,5 @@ ...@@ -228,3 +228,5 @@
"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat",
"Option '%s' användes två gånger", "Option '%s' användes två gånger",
"Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)", "Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)",
"Subselect return more than 1 field",
"Subselect return more than 1 record",
...@@ -233,3 +233,5 @@ ...@@ -233,3 +233,5 @@
"Mixing of transactional and non-transactional tables is disabled", "Mixing of transactional and non-transactional tables is disabled",
"Option '%s' used twice in statement", "Option '%s' used twice in statement",
"User '%-64s' has exceeded the '%s' resource (current value: %ld)", "User '%-64s' has exceeded the '%s' resource (current value: %ld)",
"i i i 1 ",
"i i i 1 ",
...@@ -774,3 +774,30 @@ bool select_dump::send_eof() ...@@ -774,3 +774,30 @@ bool select_dump::send_eof()
file= -1; file= -1;
return error; return error;
} }
select_subselect::select_subselect(Item_subselect *item)
{
this->item=item;
}
bool select_subselect::send_data(List<Item> &items)
{
if (item->executed){
my_printf_error(ER_SUBSELECT_NO_1_ROW, ER(ER_SUBSELECT_NO_1_ROW), MYF(0));
return 1;
}
Item *val_item= (Item *)item->select_lex->item_list.head();
if ((item->null_value= val_item->is_null()))
{
item->assign_null();
} else {
item->max_length= val_item->max_length;
item->decimals= val_item->decimals;
item->binary= val_item->binary;
val_item->val_str(&item->str_value);
item->int_value= val_item->val_int();
item->real_value= val_item->val();
item->res_type= val_item->result_type();
}
return 0;
}
...@@ -685,6 +685,19 @@ class select_union :public select_result { ...@@ -685,6 +685,19 @@ class select_union :public select_result {
bool flush(); bool flush();
}; };
/* Single value subselect interface class */
class select_subselect :public select_result
{
Item_subselect *item;
public:
select_subselect(Item_subselect *item);
bool send_fields(List<Item> &list, uint flag) { return 0; };
bool send_data(List<Item> &items);
bool send_eof() { return 0; };
friend class Ttem_subselect;
};
/* Structs used when sorting */ /* Structs used when sorting */
typedef struct st_sort_field { typedef struct st_sort_field {
......
...@@ -901,6 +901,7 @@ void st_select_lex_node::init_select() ...@@ -901,6 +901,7 @@ void st_select_lex_node::init_select()
void st_select_lex_unit::init_query() void st_select_lex_unit::init_query()
{ {
linkage= GLOBAL_OPTIONS_TYPE;
st_select_lex_node::init_query(); st_select_lex_node::init_query();
global_parameters= this; global_parameters= this;
select_limit_cnt= HA_POS_ERROR; select_limit_cnt= HA_POS_ERROR;
......
This diff is collapsed.
This diff is collapsed.
...@@ -149,8 +149,7 @@ class TMP_TABLE_PARAM { ...@@ -149,8 +149,7 @@ class TMP_TABLE_PARAM {
} }
}; };
class JOIN :public Sql_alloc{
class JOIN {
public: public:
JOIN_TAB *join_tab,**best_ref,**map2table; JOIN_TAB *join_tab,**best_ref,**map2table;
TABLE **table,**all_tables,*sort_by_table; TABLE **table,**all_tables,*sort_by_table;
...@@ -175,6 +174,70 @@ class JOIN { ...@@ -175,6 +174,70 @@ class JOIN {
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
// unit structure (with global parameters) for this select // unit structure (with global parameters) for this select
SELECT_LEX_UNIT *unit; SELECT_LEX_UNIT *unit;
// select that processed
SELECT_LEX *select_lex;
bool select_distinct, //Is select distinct?
no_order, simple_order, simple_group,
skip_sort_order, need_tmp,
hidden_group_fields,
buffer_result;
DYNAMIC_ARRAY keyuse;
Item::cond_result cond_value;
List<Item> all_fields;
List<Item> & fields_list; // hold field list passed to mysql_select
int error;
ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
COND *conds; // ---"---
TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_selec
SQL_SELECT *select; //created in optimisation phase
TABLE *exec_tmp_table; //used in 'exec' to hold temporary
my_bool test_function_query; // need to return select items 1 row
const char *zero_result_cause; // not 0 if exec must return zero result
JOIN(THD *thd, List<Item> &fields,
ulong select_options, select_result *result):
join_tab(0),
table(0),
tables(0), const_tables(0),
sort_and_group(0), first_record(0),
do_send_rows(1),
send_records(0), found_records(0), examined_rows(0),
thd(thd),
sum_funcs(0),
having(0),
select_options(select_options),
result(result),
lock(thd->lock),
select_lex(0), //for safety
select_distinct(test(select_options & SELECT_DISTINCT)),
no_order(0), simple_order(0), simple_group(0), skip_sort_order(0),
need_tmp(0),
hidden_group_fields (0), /*safety*/
buffer_result(test(select_options & OPTION_BUFFER_RESULT) &&
!test(select_options & OPTION_FOUND_ROWS)),
all_fields(fields),
fields_list(fields),
select(0),
exec_tmp_table(0),
test_function_query(0),
zero_result_cause(0)
{
fields_list = fields;
bzero((char*) &keyuse,sizeof(keyuse));
tmp_table_param.copy_field=0;
tmp_table_param.end_write_records= HA_POS_ERROR;
}
int prepare(TABLE_LIST *tables,
COND *conds, ORDER *order, ORDER *group, Item *having,
ORDER *proc_param, SELECT_LEX *select, SELECT_LEX_UNIT *unit);
int optimize();
int global_optimize();
void exec();
int cleanup(THD *thd);
}; };
......
***************
*** 173,178 ****
select_result *result;
TMP_TABLE_PARAM tmp_table_param;
MYSQL_LOCK *lock;
};
--- 172,240 ----
select_result *result;
TMP_TABLE_PARAM tmp_table_param;
MYSQL_LOCK *lock;
+
+ bool select_distinct, //Is select distinct?
+ no_order, simple_order, simple_group,
+ skip_sort_order, need_tmp,
+ hidden_group_fields,
+ buffer_result;
+ DYNAMIC_ARRAY keyuse;
+ Item::cond_result cond_value;
+ List<Item> all_fields;
+ List<Item> & fields_list; // hold field list passed to mysql_select
+ int error;
+
+ ORDER *order, *group_list, *proc_param; //hold parameters of mysql_select
+ COND *conds; // ---"---
+ TABLE_LIST *tables_list; //hold 'tables' parameter of mysql_select
+ SQL_SELECT *select; //created in optimisation phase
+ TABLE *exec_tmp_table; //used in 'exec' to hold temporary table
+ SELECT_LEX *select_lex; //corresponding select_lex
+
+ my_bool test_function_query; // need to return select items 1 row
+ const char *zero_result_cause; // not 0 if exec must return zero result
+
+ JOIN(THD *thd, List<Item> &fields,
+ ulong select_options, select_result *result):
+ join_tab(0),
+ table(0),
+ tables(0), const_tables(0),
+ sort_and_group(0), first_record(0),
+ do_send_rows(1),
+ send_records(0), found_records(0), examined_rows(0),
+ thd(thd),
+ sum_funcs(0),
+ having(0),
+ select_options(select_options),
+ result(result),
+ lock(thd->lock),
+ select_distinct(test(select_options & SELECT_DISTINCT)),
+ no_order(0), simple_order(0), simple_group(0), skip_sort_order(0),
+ need_tmp(0),
+ hidden_group_fields (0), /*safety*/
+ buffer_result(test(select_options & OPTION_BUFFER_RESULT) &&
+ !test(select_options & OPTION_FOUND_ROWS)),
+ all_fields(fields),
+ fields_list(fields),
+ select(0),
+ exec_tmp_table(0),
+ select_lex(0), //for safety
+ test_function_query(0),
+ zero_result_cause(0)
+ {
+ fields_list = fields;
+ bzero((char*) &keyuse,sizeof(keyuse));
+ tmp_table_param.copy_field=0;
+ tmp_table_param.end_write_records= HA_POS_ERROR;
+ }
+
+ int prepare(TABLE_LIST *tables,
+ COND *conds, ORDER *order, ORDER *group, Item *having,
+ ORDER *proc_param, SELECT_LEX *select);
+ int optimize();
+ int global_optimize();
+ void exec();
+ int cleanup(THD *thd);
};
***************
*** 187,193 ****
bool store_val_in_field(Field *field,Item *val);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
- bool allow_distinct_limit, ulong select_options);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);
--- 249,256 ----
bool store_val_in_field(Field *field,Item *val);
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
+ bool allow_distinct_limit, ulong select_options,
+ SELECT_LEX *first_select);
void free_tmp_table(THD *thd, TABLE *entry);
void count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
bool reset_with_sum_func);
...@@ -40,17 +40,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ...@@ -40,17 +40,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
DBUG_ENTER("mysql_union"); DBUG_ENTER("mysql_union");
st_select_lex_node * global; st_select_lex_node * global;
/* Fix tables 'to-be-unioned-from' list to point at opened tables */
for (sl= &lex->select_lex;
sl;
sl= (SELECT_LEX *) sl->next)
{
for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
cursor;
cursor=cursor->next)
cursor->table= cursor->table_list->table;
}
/* Global option */ /* Global option */
if (((void*)(global= unit->global_parameters)) == ((void*)unit)) if (((void*)(global= unit->global_parameters)) == ((void*)unit))
{ {
......
...@@ -544,7 +544,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -544,7 +544,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
literal text_literal insert_ident order_ident literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
using_list using_list subselect subselect_init
%type <item_list> %type <item_list>
expr_list udf_expr_list when_list ident_list ident_list_arg expr_list udf_expr_list when_list ident_list ident_list_arg
...@@ -612,7 +612,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -612,7 +612,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild union union_list single_multi table_wild_list table_wild_one opt_wild union union_list
precision union_option precision union_option subselect_start subselect_end
END_OF_INPUT END_OF_INPUT
%type <NONE> %type <NONE>
...@@ -1547,8 +1547,8 @@ optional_braces: ...@@ -1547,8 +1547,8 @@ optional_braces:
| '(' ')' {} | '(' ')' {}
/* all possible expressions */ /* all possible expressions */
expr: expr_expr {$$ = $1; } expr: expr_expr { $$= $1; }
| simple_expr {$$ = $1; } | simple_expr { $$= $1; }
/* expressions that begin with 'expr' */ /* expressions that begin with 'expr' */
expr_expr: expr_expr:
...@@ -1688,6 +1688,7 @@ simple_expr: ...@@ -1688,6 +1688,7 @@ simple_expr:
| NOT expr %prec NEG { $$= new Item_func_not($2); } | NOT expr %prec NEG { $$= new Item_func_not($2); }
| '!' expr %prec NEG { $$= new Item_func_not($2); } | '!' expr %prec NEG { $$= new Item_func_not($2); }
| '(' expr ')' { $$= $2; } | '(' expr ')' { $$= $2; }
| subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; } | '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' expr ')' | MATCH ident_list_arg AGAINST '(' expr ')'
{ Select->ftfunc_list.push_back((Item_func_match *) { Select->ftfunc_list.push_back((Item_func_match *)
...@@ -3849,3 +3850,30 @@ optional_order_or_limit: ...@@ -3849,3 +3850,30 @@ optional_order_or_limit:
union_option: union_option:
/* empty */ {} /* empty */ {}
| ALL {Lex->union_option=1;} | ALL {Lex->union_option=1;}
subselect:
subselect_start subselect_init
subselect_end
{
$$= $2;
}
subselect_init:
select_init
{
$$= new Item_subselect(current_thd, Lex->select);
}
subselect_start:
'('
{
if (mysql_new_select(Lex, 1))
YYABORT;
}
subselect_end:
')'
{
LEX *lex=Lex;
lex->select = (SELECT_LEX*)lex->select->master->master;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment