diff options
author | unknown <bell@sanja.is.com.ua> | 2003-04-23 11:20:19 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2003-04-23 11:20:19 +0300 |
commit | 711eb800ad610fcdff2087b41a9aa38fe8d6bae9 (patch) | |
tree | f990ceb0b0676587ce26deb5505e45e1cfcf7e72 | |
parent | b648068856f8bc2a636fc3ce0a49a7128b6bd6c6 (diff) | |
parent | 0c1af74d8aeafa09e2f216b0758204828ab47f9e (diff) | |
download | mariadb-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.result | 8 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 5 | ||||
-rw-r--r-- | sql/sql_lex.cc | 55 | ||||
-rw-r--r-- | sql/sql_lex.h | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 11 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 2 |
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(); }; |