mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
simple subselects ported to new select_lex structures
This commit is contained in:
@ -243,4 +243,6 @@
|
||||
#define ER_MIXING_NOT_ALLOWED 1224
|
||||
#define ER_DUP_ARGUMENT 1225
|
||||
#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 \
|
||||
hostname.cc init.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_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 \
|
||||
opt_sum.cc procedure.cc records.cc sql_acl.cc \
|
||||
repl_failsafe.cc slave.cc \
|
||||
|
31
mysql-test/r/subselect.result
Normal file
31
mysql-test/r/subselect.result
Normal file
@ -0,0 +1,31 @@
|
||||
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;
|
18
mysql-test/t/subselect.test
Normal file
18
mysql-test/t/subselect.test
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#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@ \
|
||||
$(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@
|
||||
noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.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 \
|
||||
sql_manager.h sql_map.h sql_string.h unireg.h \
|
||||
field.h handler.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 \
|
||||
item.cc item_sum.cc item_buff.cc item_func.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 \
|
||||
net_serv.cc net_pkg.cc lock.cc my_lock.c \
|
||||
sql_string.cc sql_manager.cc sql_map.cc \
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
enum Type {FIELD_ITEM,FUNC_ITEM,SUM_FUNC_ITEM,STRING_ITEM,
|
||||
INT_ITEM,REAL_ITEM,NULL_ITEM,VARBIN_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 };
|
||||
|
||||
String str_value; /* used to store value */
|
||||
@ -46,7 +47,6 @@ public:
|
||||
my_bool unsigned_flag;
|
||||
my_bool with_sum_func;
|
||||
|
||||
|
||||
// alloc & destruct is done as start of select using sql_alloc
|
||||
Item();
|
||||
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||
@ -371,6 +371,7 @@ public:
|
||||
#include "item_strfunc.h"
|
||||
#include "item_timefunc.h"
|
||||
#include "item_uniq.h"
|
||||
#include "item_subselect.h"
|
||||
|
||||
class Item_copy_string :public Item
|
||||
{
|
||||
@ -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 bool field_is_equal_to_item(Field *field,Item *item);
|
||||
Item *get_system_var(LEX_STRING name);
|
||||
|
||||
|
@ -38,7 +38,9 @@ public:
|
||||
Field *tmp_table_field(TABLE *t_arg)
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
136
sql/item_subselect.cc
Normal file
136
sql/item_subselect.cc
Normal file
@ -0,0 +1,136 @@
|
||||
/* 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;
|
||||
}
|
79
sql/item_subselect.h
Normal file
79
sql/item_subselect.h
Normal file
@ -0,0 +1,79 @@
|
||||
/* 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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.",
|
||||
"Optie '%s' tweemaal gebruikt in opdracht",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud",
|
||||
"M<><4D>rangut '%s' on lauses kasutatud topelt",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> transactional <20> non-transactional <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD> '%s' <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>",
|
||||
"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
|
@ -236,3 +236,5 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"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 @@
|
||||
"Blandning av transaktionella och icke-transaktionella tabeller <20>r inaktiverat",
|
||||
"Option '%s' anv<6E>ndes tv<74> g<>nger",
|
||||
"Anv<6E>ndare '%-64s' har <20>verskridit '%s' (nuvarande v<>rde: %ld)",
|
||||
"Subselect return more than 1 field",
|
||||
"Subselect return more than 1 record",
|
||||
|
@ -233,3 +233,5 @@
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Option '%s' used twice in statement",
|
||||
"User '%-64s' has exceeded the '%s' resource (current value: %ld)",
|
||||
"<22>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>i<EFBFBD><69><EFBFBD> <20>i<EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",
|
||||
"<22>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>i<EFBFBD><69><EFBFBD> <20>i<EFBFBD> 1 <20><><EFBFBD><EFBFBD><EFBFBD>",
|
||||
|
@ -774,3 +774,30 @@ bool select_dump::send_eof()
|
||||
file= -1;
|
||||
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 {
|
||||
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 */
|
||||
|
||||
typedef struct st_sort_field {
|
||||
|
@ -901,6 +901,7 @@ void st_select_lex_node::init_select()
|
||||
|
||||
void st_select_lex_unit::init_query()
|
||||
{
|
||||
linkage= GLOBAL_OPTIONS_TYPE;
|
||||
st_select_lex_node::init_query();
|
||||
global_parameters= this;
|
||||
select_limit_cnt= HA_POS_ERROR;
|
||||
|
File diff suppressed because it is too large
Load Diff
1576
sql/sql_select.cc.rej
Normal file
1576
sql/sql_select.cc.rej
Normal file
File diff suppressed because it is too large
Load Diff
@ -149,8 +149,7 @@ class TMP_TABLE_PARAM {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class JOIN {
|
||||
class JOIN :public Sql_alloc{
|
||||
public:
|
||||
JOIN_TAB *join_tab,**best_ref,**map2table;
|
||||
TABLE **table,**all_tables,*sort_by_table;
|
||||
@ -175,6 +174,70 @@ class JOIN {
|
||||
MYSQL_LOCK *lock;
|
||||
// unit structure (with global parameters) for this select
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
96
sql/sql_select.h.rej
Normal file
96
sql/sql_select.h.rej
Normal file
@ -0,0 +1,96 @@
|
||||
***************
|
||||
*** 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)
|
||||
DBUG_ENTER("mysql_union");
|
||||
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 */
|
||||
if (((void*)(global= unit->global_parameters)) == ((void*)unit))
|
||||
{
|
||||
|
@ -544,7 +544,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
literal text_literal insert_ident order_ident
|
||||
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
|
||||
using_list
|
||||
using_list subselect subselect_init
|
||||
|
||||
%type <item_list>
|
||||
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);
|
||||
table_to_table_list table_to_table opt_table_list opt_as
|
||||
handler_rkey_function handler_read_or_scan
|
||||
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
|
||||
|
||||
%type <NONE>
|
||||
@ -1547,8 +1547,8 @@ optional_braces:
|
||||
| '(' ')' {}
|
||||
|
||||
/* all possible expressions */
|
||||
expr: expr_expr {$$ = $1; }
|
||||
| simple_expr {$$ = $1; }
|
||||
expr: expr_expr { $$= $1; }
|
||||
| simple_expr { $$= $1; }
|
||||
|
||||
/* expressions that begin with 'expr' */
|
||||
expr_expr:
|
||||
@ -1688,6 +1688,7 @@ simple_expr:
|
||||
| NOT expr %prec NEG { $$= new Item_func_not($2); }
|
||||
| '!' expr %prec NEG { $$= new Item_func_not($2); }
|
||||
| '(' expr ')' { $$= $2; }
|
||||
| subselect { $$= $1; }
|
||||
| '{' ident expr '}' { $$= $3; }
|
||||
| MATCH ident_list_arg AGAINST '(' expr ')'
|
||||
{ Select->ftfunc_list.push_back((Item_func_match *)
|
||||
@ -3849,3 +3850,30 @@ optional_order_or_limit:
|
||||
union_option:
|
||||
/* empty */ {}
|
||||
| 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user