diff options
author | unknown <bell@sanja.is.com.ua> | 2003-06-28 14:32:06 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2003-06-28 14:32:06 +0300 |
commit | 6a854da78c16b096b0b15042d754b36b442188cc (patch) | |
tree | bdb7e2f08be4378ed2122950490775eb67e71922 | |
parent | be9af553fbefb2af15cffe159c71aeaf8db400c9 (diff) | |
parent | de5e96e443c2509a5750ef2c8569430fbdbb2722 (diff) | |
download | mariadb-git-6a854da78c16b096b0b15042d754b36b442188cc.tar.gz |
Merge
sql/item.cc:
Auto merged
mysql-test/r/subselect.result:
SCCS merged
mysql-test/t/subselect.test:
SCCS merged
-rw-r--r-- | mysql-test/r/subselect.result | 5 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 10 | ||||
-rw-r--r-- | sql/item.cc | 78 |
3 files changed, 66 insertions, 27 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f3241e27173..486cab68557 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1153,6 +1153,11 @@ INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL); SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2); REF_ID DROP TABLE t1; +create table t1(City VARCHAR(30),Location geometry); +insert into t1 values("Paris",GeomFromText('POINT(2.33 48.87)')); +select City from t1 where (select intersects(GeomFromText(AsText(Location)),GeomFromText('Polygon((2 50, 2.5 50, 2.5 47, 2 47, 2 50))'))=0); +City +drop table t1; CREATE TABLE `t1` ( `id` mediumint(8) unsigned NOT NULL auto_increment, `pseudo` varchar(35) NOT NULL default '', diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d77d49f303b..0c3c5cfda18 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -738,6 +738,16 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL); SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2); DROP TABLE t1; + + +# +# correct behavoiur for function from reduced subselect +# +create table t1(City VARCHAR(30),Location geometry); +insert into t1 values("Paris",GeomFromText('POINT(2.33 48.87)')); +select City from t1 where (select intersects(GeomFromText(AsText(Location)),GeomFromText('Polygon((2 50, 2.5 50, 2.5 47, 2 47, 2 50))'))=0); +drop table t1; + # # reduced subselect in ORDER BY & GROUP BY clauses # diff --git a/sql/item.cc b/sql/item.cc index 75651917923..3ea537a19de 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -23,6 +23,10 @@ #include <m_ctype.h> #include "my_dir.h" +static void mark_as_dependent(bool outer_resolving, + SELECT_LEX *last, SELECT_LEX_NODE *current, + Item_ident *item); + /***************************************************************************** ** Item functions *****************************************************************************/ @@ -786,6 +790,37 @@ bool Item_ref_null_helper::get_date(TIME *ltime, bool fuzzydate) return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate)); } + +/* + Mark item and SELECT_LEXs as dependent if it is not outer resolving + + SYNOPSIS + mark_as_dependent() + outer_resolving - flag of outer resolving + last - select from which current item depend + current - current select + item - item which should be marked +*/ + +static void mark_as_dependent(bool outer_resolving, + SELECT_LEX *last, SELECT_LEX_NODE *current, + Item_ident *item) +{ + /* + only last check is need, i.e. + "last != current" + first check added for speed up (check boolean should be faster + then comparing pointers and this condition usually true) + */ + if (!outer_resolving || ((SELECT_LEX_NODE *)last) != current) + { + // store pointer on SELECT_LEX from wich item is dependent + item->depended_from= last; + current->mark_as_dependent(last); + } +} + + bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { if (!field) // If field is not checked @@ -857,29 +892,22 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return -1; } - Item_ref *r; - *ref= r= new Item_ref(last->ref_pointer_array + counter - , (char *)table_name, - (char *)field_name); - if (!r) + Item_ref *rf; + *ref= rf= new Item_ref(last->ref_pointer_array + counter, + (char *)table_name, + (char *)field_name); + if (!rf) return 1; - if (r->fix_fields(thd, tables, ref) || r->check_cols(1)) + if (rf->fix_fields(thd, tables, ref) || rf->check_cols(1)) return 1; - // store pointer on SELECT_LEX from which item is dependent - r->depended_from= last; - cursel->mark_as_dependent(last); + + mark_as_dependent(outer_resolving, last, cursel, rf); return 0; } else { - // store pointer on SELECT_LEX from wich item is dependent - depended_from= last; - /* - Mark all selects from resolved to 1 before select where was - found table as depended (of select where was found table) - */ - thd->lex.current_select->mark_as_dependent(last); - if (depended_from->having_fix_field) + mark_as_dependent(outer_resolving, last, cursel, this); + if (last->having_fix_field) { Item_ref *rf; *ref= rf= new Item_ref((where->db[0]?where->db:0), @@ -1351,12 +1379,10 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) else if (tmp != not_found_field) { ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item - Item_field* f; - if (!((*reference)= f= new Item_field(tmp))) + Item_field* fld; + if (!((*reference)= fld= new Item_field(tmp))) return 1; - // store pointer on SELECT_LEX from wich item is dependent - f->depended_from= last; - thd->lex.current_select->mark_as_dependent(last); + mark_as_dependent(outer_resolving, last, thd->lex.current_select, fld); return 0; } else @@ -1367,11 +1393,9 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) "forward reference in item list"); return -1; } - /* - depended_from: pointer on SELECT_LEX from wich item is dependent - */ - ref= (depended_from= last)->ref_pointer_array + counter; - thd->lex.current_select->mark_as_dependent(last); + mark_as_dependent(outer_resolving, last, thd->lex.current_select, + this); + ref= last->ref_pointer_array + counter; } } else if (!ref) |