summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2003-04-23 11:20:19 +0300
committerunknown <bell@sanja.is.com.ua>2003-04-23 11:20:19 +0300
commit711eb800ad610fcdff2087b41a9aa38fe8d6bae9 (patch)
treef990ceb0b0676587ce26deb5505e45e1cfcf7e72
parentb648068856f8bc2a636fc3ce0a49a7128b6bd6c6 (diff)
parent0c1af74d8aeafa09e2f216b0758204828ab47f9e (diff)
downloadmariadb-git-711eb800ad610fcdff2087b41a9aa38fe8d6bae9.tar.gz
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-order-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_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged
-rw-r--r--mysql-test/r/subselect.result8
-rw-r--r--mysql-test/t/subselect.test5
-rw-r--r--sql/sql_lex.cc55
-rw-r--r--sql/sql_lex.h8
-rw-r--r--sql/sql_parse.cc11
-rw-r--r--sql/sql_yacc.yy2
6 files changed, 76 insertions, 13 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 846e54f12ef..564e102c874 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -458,6 +458,14 @@ Subselect returns more than 1 record
select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
Subselect returns more than 1 record
drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
INSERT INTO t1 VALUES ();
SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 97c3b0523b4..dffe6ec79c2 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -244,6 +244,11 @@ select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+drop table t1;
+
#iftest
CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
INSERT INTO t1 VALUES ();
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d5d438fc3a1..d88908d9e0f 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1203,23 +1203,60 @@ TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
}
ulong st_select_lex_node::get_table_join_options() { return 0; }
-/*
- This is used for UNION & subselect to create a new table list of all used
- tables.
- The table_list->table entry in all used tables are set to point
- to the entries in this list.
-*/
-// interface
+/*
+ Interface method of table list creation for query
+
+ SYNOPSIS
+ st_select_lex_unit::create_total_list()
+ thd THD pointer
+ result pointer on result list of tables pointer
+ check_derived force derived table chacking (used for creating
+ table list for derived query)
+ DESCRIPTION
+ This is used for UNION & subselect to create a new table list of all used
+ tables.
+ The table_list->table entry in all used tables are set to point
+ to the entries in this list.
+
+ RETURN
+ 0 - OK
+ !0 - error
+*/
bool st_select_lex_unit::create_total_list(THD *thd, st_lex *lex,
TABLE_LIST **result,
bool check_derived)
{
*result= 0;
- return create_total_list_n_last_return(thd, lex, &result, check_derived);
+ for (SELECT_LEX_UNIT *unit= this; unit; unit= unit->next_unit())
+ {
+ if ((res= unit->create_total_list_n_last_return(thd, lex, &result,
+ check_derived)))
+ return res;
+ }
+ return 0;
}
-// list creator
+/*
+ Table list creation for query
+
+ SYNOPSIS
+ st_select_lex_unit::create_total_list()
+ thd THD pointer
+ lex pointer on LEX stricture
+ result pointer on pointer on result list of tables pointer
+ check_derived force derived table chacking (used for creating
+ table list for derived query)
+ DESCRIPTION
+ This is used for UNION & subselect to create a new table list of all used
+ tables.
+ The table_list->table entry in all used tables are set to point
+ to the entries in this list.
+
+ RETURN
+ 0 - OK
+ !0 - error
+*/
bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex,
TABLE_LIST ***result,
bool check_derived)
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 9fb0f8cfdf5..75ec2f2d3fb 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -230,6 +230,7 @@ public:
virtual st_select_lex_unit* master_unit()= 0;
virtual st_select_lex* outer_select()= 0;
+ virtual st_select_lex_node* return_after_parsing()= 0;
virtual bool set_braces(bool value);
virtual bool inc_in_sum_expr();
@@ -284,6 +285,8 @@ public:
global parameters for union
*/
st_select_lex_node *global_parameters;
+ //node on wich we should return current_select pointer after parsing subquery
+ st_select_lex_node *return_to;
/* LIMIT clause runtime counters */
ha_rows select_limit_cnt, offset_limit_cnt;
/* not NULL if union used in subselect, point to subselect item */
@@ -304,6 +307,7 @@ public:
(st_select_lex*) slave->next : (st_select_lex*) slave;
}
st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; }
+ st_select_lex_node* return_after_parsing() { return return_to; }
void exclude_level();
/* UNION methods */
@@ -366,6 +370,10 @@ public:
{
return &link_next;
}
+ st_select_lex_node* return_after_parsing()
+ {
+ return master_unit()->return_after_parsing();
+ }
bool set_braces(bool value);
bool inc_in_sum_expr();
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2f4915c74f1..d0a970c98b7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3235,7 +3235,8 @@ mysql_init_query(THD *thd)
lex->select_lex.init_query();
lex->value_list.empty();
lex->param_list.empty();
- lex->unit.next= lex->unit.master= lex->unit.link_next= 0;
+ lex->unit.next= lex->unit.master= lex->unit.return_to=
+ lex->unit.link_next= 0;
lex->unit.prev= lex->unit.link_prev= 0;
lex->unit.global_parameters= lex->unit.slave= lex->current_select=
lex->all_selects_list= &lex->select_lex;
@@ -3283,9 +3284,9 @@ bool
mysql_new_select(LEX *lex, bool move_down)
{
SELECT_LEX *select_lex = new SELECT_LEX();
- select_lex->select_number= ++lex->thd->select_number;
if (!select_lex)
return 1;
+ select_lex->select_number= ++lex->thd->select_number;
select_lex->init_query();
select_lex->init_select();
if (move_down)
@@ -3297,9 +3298,13 @@ mysql_new_select(LEX *lex, bool move_down)
unit->init_query();
unit->init_select();
unit->thd= lex->thd;
- unit->include_down(lex->current_select);
+ if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
+ unit->include_neighbour(lex->current_select);
+ else
+ unit->include_down(lex->current_select);
unit->link_next= 0;
unit->link_prev= 0;
+ unit->return_to= lex->current_select;
select_lex->include_down(unit);
}
else
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d312bc5571f..5664c46349a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5014,5 +5014,5 @@ subselect_end:
')'
{
LEX *lex=Lex;
- lex->current_select = lex->current_select->outer_select();
+ lex->current_select = lex->current_select->return_after_parsing();
};