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

prevent using expernal fields in derived tables

parent 46a74ce7
...@@ -240,4 +240,6 @@ SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FRO ...@@ -240,4 +240,6 @@ SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FRO
numeropost maxnumrep numeropost maxnumrep
43506 2 43506 2
40143 1 40143 1
SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1);
Unknown column 'a' in 'having clause'
drop table forumconthardwarefr7, searchconthardwarefr7; drop table forumconthardwarefr7, searchconthardwarefr7;
...@@ -137,5 +137,7 @@ CREATE TABLE `searchconthardwarefr7` ( ...@@ -137,5 +137,7 @@ CREATE TABLE `searchconthardwarefr7` (
INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce'); INSERT INTO searchconthardwarefr7 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; SELECT numeropost,maxnumrep FROM forumconthardwarefr7 WHERE exists (SELECT 1 FROM searchconthardwarefr7 WHERE (mot='joce') AND date >= '2002-10-21' AND forumconthardwarefr7.numeropost = searchconthardwarefr7.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
-- error 1054
SELECT (SELECT 1) as a FROM (SELECT 1 FROM forumconthardwarefr7 HAVING a=1);
drop table forumconthardwarefr7, searchconthardwarefr7; drop table forumconthardwarefr7, searchconthardwarefr7;
\ No newline at end of file
...@@ -444,6 +444,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -444,6 +444,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
cause error ER_NON_UNIQ_ERROR in find_field_in_tables. cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/ */
SELECT_LEX *last= 0; SELECT_LEX *last= 0;
// Prevent using outer fields in subselects, that is not supported now
if (thd->lex.current_select->linkage != DERIVED_TABLE_TYPE)
for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); for (SELECT_LEX *sl= thd->lex.current_select->outer_select();
sl; sl;
sl= sl->outer_select()) sl= sl->outer_select())
...@@ -812,9 +815,17 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -812,9 +815,17 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
if (!ref) if (!ref)
{ {
SELECT_LEX *sl= thd->lex.current_select->outer_select(); SELECT_LEX *sl= thd->lex.current_select->outer_select();
/*
Finding only in current select will be performed for selects that have
not outer one and for derived tables (which not support using outer
fields for now)
*/
if ((ref= find_item_in_list(this, if ((ref= find_item_in_list(this,
*(thd->lex.current_select->get_item_list()), *(thd->lex.current_select->get_item_list()),
(sl ? REPORT_EXCEPT_NOT_FOUND : ((sl &&
thd->lex.current_select->linkage !=
DERIVED_TABLE_TYPE) ?
REPORT_EXCEPT_NOT_FOUND :
REPORT_ALL_ERRORS))) == REPORT_ALL_ERRORS))) ==
(Item **)not_found_item) (Item **)not_found_item)
{ {
......
...@@ -95,12 +95,16 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) ...@@ -95,12 +95,16 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
if (unit->select_limit_cnt == HA_POS_ERROR) if (unit->select_limit_cnt == HA_POS_ERROR)
sl->options&= ~OPTION_FOUND_ROWS; sl->options&= ~OPTION_FOUND_ROWS;
SELECT_LEX_NODE *save_current_select= lex->current_select;
lex->current_select= sl;
res= mysql_select(thd, tables, sl->item_list, res= mysql_select(thd, tables, sl->item_list,
sl->where, (ORDER *) sl->order_list.first, sl->where, (ORDER *) sl->order_list.first,
(ORDER*) sl->group_list.first, (ORDER*) sl->group_list.first,
sl->having, (ORDER*) NULL, sl->having, (ORDER*) NULL,
sl->options | thd->options | SELECT_NO_UNLOCK, sl->options | thd->options | SELECT_NO_UNLOCK,
derived_result, unit, sl, 0); derived_result, unit, sl, 0);
lex->current_select= save_current_select;
if (!res) if (!res)
{ {
// Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables // Here we entirely fix both TABLE_LIST and list of SELECT's as there were no derived tables
......
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