diff options
author | unknown <monty@hundin.mysql.fi> | 2002-10-17 11:39:11 +0300 |
---|---|---|
committer | unknown <monty@hundin.mysql.fi> | 2002-10-17 11:39:11 +0300 |
commit | 5d2e98ff5f29bbad52b7b57319ba0542b5d94d48 (patch) | |
tree | d161390278c18d0d52db3a76f4d39a24b7c29770 | |
parent | f64428be11b4cf2006c8998b251195dfac565a36 (diff) | |
parent | 620b2e6e8b42d62cecec69b696c9781faa86d29e (diff) | |
download | mariadb-git-5d2e98ff5f29bbad52b7b57319ba0542b5d94d48.tar.gz |
merge
Docs/world.sql:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_select.cc:
Auto merged
-rw-r--r-- | mysql-test/r/heap_btree.result | 2 | ||||
-rw-r--r-- | mysql-test/r/select.result | 10 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 24 | ||||
-rw-r--r-- | mysql-test/t/select.test | 4 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 20 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 54 | ||||
-rw-r--r-- | sql/sql_class.h | 12 | ||||
-rw-r--r-- | sql/sql_lex.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 97 | ||||
-rw-r--r-- | sql/sql_select.cc | 94 | ||||
-rw-r--r-- | sql/sql_union.cc | 12 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 138 |
14 files changed, 336 insertions, 138 deletions
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 0e8a32bd7b7..846a852738b 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -73,8 +73,8 @@ type=heap; insert into t1 values (1,1),(2,2),(1,3),(2,4),(2,5),(2,6); select * from t1 where x=1; x y -1 1 1 3 +1 1 select * from t1,t1 as t2 where t1.x=t2.y; x y x y 1 1 1 1 diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 925f754f203..3a15e419fa5 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3266,6 +3266,16 @@ select wss_type from t1 where wss_type =102935229216544093; wss_type 102935229216544093 drop table t1; +select 1+2,"aaaa",3.13*2.0 into @a,@b,@c; +select @a; +@a +3 +select @b; +@b +aaaa +select @c; +@c +6.26 create table t1 (a int not null auto_increment primary key); insert into t1 values (); insert into t1 values (); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c365c2ed434..2dcafe2c9cb 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -54,9 +54,9 @@ explain select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 2 where used +2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 Using filesort 3 UNION t4 ALL NULL NULL NULL NULL 3 where used; Using filesort 4 SUBSELECT t2 ALL NULL NULL NULL NULL 2 -2 SUBSELECT t3 ALL NULL NULL NULL NULL 3 Using filesort select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a 3 1 @@ -163,9 +163,7 @@ UNIQUE KEY `email` (`email`) INSERT INTO inscrit (pseudo,email) VALUES ('joce','test'); INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1'); INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1'); -EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT -pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT -pseudo FROM inscrit WHERE pseudo='joce'); +EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY inscrit const PRIMARY PRIMARY 35 const 1 4 SUBSELECT inscrit const PRIMARY PRIMARY 35 const 1 @@ -183,3 +181,21 @@ joce SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%'); Subselect returns more than 1 record drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; +drop table if exists searchconthardwarefr3; +CREATE TABLE `searchconthardwarefr3` ( +`topic` mediumint(8) unsigned NOT NULL default '0', +`date` date NOT NULL default '0000-00-00', +`pseudo` varchar(35) character set latin1 NOT NULL default '', +PRIMARY KEY (`pseudo`,`date`,`topic`), +KEY `topic` (`topic`) +) TYPE=MyISAM ROW_FORMAT=DYNAMIC; +INSERT INTO searchconthardwarefr3 (topic,date,pseudo) VALUES +('43506','2002-10-02','joce'),('40143','2002-08-03','joce'); +EXPLAIN SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE searchconthardwarefr3 index NULL PRIMARY 41 NULL 2 where used; Using index +EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY No tables used +2 SUBSELECT searchconthardwarefr3 index NULL PRIMARY 41 NULL 2 where used; Using index +drop table searchconthardwarefr3; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 15d44bcd672..34ad496f285 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1751,6 +1751,10 @@ select wss_type from t1 where wss_type ='102935229216544104'; select wss_type from t1 where wss_type ='102935229216544093'; select wss_type from t1 where wss_type =102935229216544093; drop table t1; +select 1+2,"aaaa",3.13*2.0 into @a,@b,@c; +select @a; +select @b; +select @c; # # Test of removing redundant braces in the FROM part diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index dbf45262a1e..518ade7fcf7 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -83,9 +83,7 @@ CREATE TABLE `inscrit` ( INSERT INTO inscrit (pseudo,email) VALUES ('joce','test'); INSERT INTO inscrit (pseudo,email) VALUES ('joce1','test1'); INSERT INTO inscrit (pseudo,email) VALUES ('2joce1','2test1'); -EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT -pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT -pseudo FROM inscrit WHERE pseudo='joce'); +EXPLAIN SELECT pseudo,(SELECT email FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce')) FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo='joce'); -- error 1239 SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo,email FROM inscrit WHERE pseudo='joce'); @@ -96,4 +94,18 @@ SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo -- error 1240 SELECT pseudo FROM inscrit WHERE pseudo=(SELECT pseudo FROM inscrit WHERE pseudo LIKE '%joce%'); -drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit;
\ No newline at end of file +drop table if exists t1,t2,t3,t4,t5,attend,clinic,inscrit; + +drop table if exists searchconthardwarefr3; +CREATE TABLE `searchconthardwarefr3` ( + `topic` mediumint(8) unsigned NOT NULL default '0', + `date` date NOT NULL default '0000-00-00', + `pseudo` varchar(35) character set latin1 NOT NULL default '', + PRIMARY KEY (`pseudo`,`date`,`topic`), + KEY `topic` (`topic`) +) TYPE=MyISAM ROW_FORMAT=DYNAMIC; +INSERT INTO searchconthardwarefr3 (topic,date,pseudo) VALUES +('43506','2002-10-02','joce'),('40143','2002-08-03','joce'); +EXPLAIN SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'; +EXPLAIN SELECT (SELECT DISTINCT date FROM searchconthardwarefr3 WHERE date='2002-08-03'); +drop table searchconthardwarefr3;
\ No newline at end of file diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 6b8c4fd1f14..d1a3c7e235a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -392,6 +392,8 @@ int mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &list,COND *conds, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, bool fake_select_lex); void fix_tables_pointers(SELECT_LEX *select_lex); +int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, + select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, select_result *result); int mysql_union(THD *thd, LEX *lex,select_result *result); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f778a721f54..083b0ed2543 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -912,3 +912,57 @@ bool select_exists_subselect::send_data(List<Item> &items) DBUG_RETURN(0); } + +/*************************************************************************** +** Dump of select to variables +***************************************************************************/ +int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) +{ + List_iterator_fast<Item> li(list); + List_iterator_fast<LEX_STRING> gl(var_list); + Item *item; + LEX_STRING *ls; + if (var_list.elements != list.elements) + { + my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); + return 1; + } + while ((item=li++)) + { + ls= gl++; + Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); + xx->fix_fields(current_thd,(TABLE_LIST*) current_thd->lex.select_lex.table_list.first,&item); + xx->fix_length_and_dec(); + vars.push_back(xx); + } + return 0; +} +bool select_dumpvar::send_data(List<Item> &items) +{ + List_iterator_fast<Item_func_set_user_var> li(vars); + Item_func_set_user_var *xx; + DBUG_ENTER("send_data"); + + if (row_count++) + { + my_error(ER_TOO_MANY_ROWS, MYF(0)); + DBUG_RETURN(1); + } + while ((xx=li++)) + xx->update(); + DBUG_RETURN(0); +} + +bool select_dumpvar::send_eof() +{ + if (row_count) + { + ::send_ok(thd,row_count); + return 0; + } + else + { + my_error(ER_EMPTY_QUERY,MYF(0)); + return 1; + } +} diff --git a/sql/sql_class.h b/sql/sql_class.h index e9a4109a4c1..7b5a6da8c6b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -966,3 +966,15 @@ public: bool send_eof(); }; +class select_dumpvar :public select_result { + ha_rows row_count; +public: + List<LEX_STRING> var_list; + List<Item_func_set_user_var> vars; + select_dumpvar(void) { var_list.empty(); vars.empty(); row_count=0;} + ~select_dumpvar() {} + int prepare(List<Item> &list, SELECT_LEX_UNIT *u); + bool send_fields(List<Item> &list, uint flag) {return 0;} + bool send_data(List<Item> &items); + bool send_eof(); +}; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 46206079084..9f09afc78a6 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -955,6 +955,7 @@ void st_select_lex::init_query() table_list.first= 0; table_list.next= (byte**) &table_list.first; item_list.empty(); + join= 0; } void st_select_lex::init_select() @@ -973,7 +974,6 @@ void st_select_lex::init_select() ftfunc_list= &ftfunc_list_alloc; linkage= UNSPECIFIED_TYPE; depended= having_fix_field= 0; - } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index f301e4c8af0..de57e9f77a8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -334,6 +334,7 @@ typedef struct st_lex enum SSL_type ssl_type; /* defined in violite.h */ String *wild; sql_exchange *exchange; + select_result *result; List<key_part_spec> col_list; List<key_part_spec> ref_list; @@ -377,7 +378,7 @@ typedef struct st_lex uint param_count; bool drop_primary, drop_if_exists, local_file, olap; bool in_comment, ignore_space, verbose, simple_alter; - bool derived_tables; + bool derived_tables, describe; uint slave_thd_opt; CHARSET_INFO *charset; } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8002684377d..046b5d45b59 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1335,8 +1335,7 @@ mysql_execute_command(THD *thd) TODO: solve problem with depended derived tables in subselects */ if (lex->sql_command == SQLCOM_SELECT && - (select_lex->options & SELECT_DESCRIBE) && - lex->derived_tables) + lex->describe && lex->derived_tables) { if (!(explain_result= new select_send())) { @@ -1404,9 +1403,7 @@ mysql_execute_command(THD *thd) switch (lex->sql_command) { case SQLCOM_SELECT: { - select_result *result; - if (select_lex->options & SELECT_DESCRIBE) - lex->exchange=0; + select_result *result=lex->result; if (tables) { res=check_table_access(thd, @@ -1431,51 +1428,10 @@ mysql_execute_command(THD *thd) if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; - if (lex->exchange) - { - if (lex->exchange->dumpfile) - { - if (!(result=new select_dump(lex->exchange))) - { - res= -1; - break; - } - } - else - { - if (!(result=new select_export(lex->exchange))) - { - res= -1; - break; - } - } - } - else if (!(result=new select_send())) - { - res= -1; -#ifdef DELETE_ITEMS - delete select_lex->having; - delete select_lex->where; -#endif - break; - } - else - { - /* - Normal select: - Change lock if we are using SELECT HIGH PRIORITY, - FOR UPDATE or IN SHARE MODE - */ - TABLE_LIST *table; - for (table = tables ; table ; table=table->next) - table->lock_type= lex->lock_option; - } - if (!(res=open_and_lock_tables(thd,tables))) { - if (select_lex->options & SELECT_DESCRIBE) + if (lex->describe) { - delete result; // we do not need it for explain if (!explain_result) if (!(explain_result= new select_send())) { @@ -1485,24 +1441,7 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(explain_result); fix_tables_pointers(select_lex); - for ( SELECT_LEX *sl= select_lex; - sl && res == 0; - sl= sl->next_select_in_list()) - { - SELECT_LEX *first= sl->master_unit()->first_select(); - res= mysql_explain_select(thd, sl, - ((select_lex==sl)? - ((sl->next_select_in_list())?"PRIMARY": - "SIMPLE"): - ((sl == first)? - ((sl->depended)?"DEPENDENT SUBSELECT": - "SUBSELECT"): - ((sl->depended)?"DEPENDENT UNION": - "UNION"))), - explain_result); - } - if (res > 0) - res= -res; // mysql_explain_select do not report error + res= mysql_explain_union(thd, &thd->lex.unit, explain_result); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; explain_result->send_eof(); @@ -1510,12 +1449,33 @@ mysql_execute_command(THD *thd) } else { + if (!result) + { + if ((result=new select_send())) + { + /* + Normal select: + Change lock if we are using SELECT HIGH PRIORITY, + FOR UPDATE or IN SHARE MODE + */ + TABLE_LIST *table; + for (table = tables ; table ; table=table->next) + table->lock_type= lex->lock_option; + } + else + { + res= -1; +#ifdef DELETE_ITEMS + delete select_lex->having; + delete select_lex->where; +#endif + break; + } + } query_cache_store_query(thd, tables); res=handle_select(thd, lex, result); } } - else - delete result; break; } case SQLCOM_DO: @@ -2946,7 +2906,7 @@ mysql_init_query(THD *thd) thd->free_list= 0; thd->lex.union_option= 0; thd->lex.select= &thd->lex.select_lex; - thd->lex.olap=0; + thd->lex.olap=thd->lex.describe=0; thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE; thd->fatal_error= 0; // Safety thd->total_warn_count=0; // Warnings for this query @@ -2966,6 +2926,7 @@ mysql_init_select(LEX *lex) lex->thd->variables.select_limit; select_lex->olap= UNSPECIFIED_OLAP_TYPE; lex->exchange= 0; + lex->result= 0; lex->proc_list.first= 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 84f8f7d180a..6a48f56443c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -216,7 +216,7 @@ JOIN::prepare(TABLE_LIST *tables_init, SELECT_LEX_UNIT *unit, bool fake_select_lex) { DBUG_ENTER("JOIN::prepare"); - + conds= conds_init; order= order_init; group_list= group_init; @@ -351,7 +351,7 @@ int JOIN::optimize() { DBUG_ENTER("JOIN::optimize"); - + #ifdef HAVE_REF_TO_FIELDS // Not done yet /* Add HAVING to WHERE if possible */ if (having && !group_list && ! sum_func_count) @@ -1043,36 +1043,60 @@ mysql_select(THD *thd, TABLE_LIST *tables, List<Item> &fields, COND *conds, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex, bool fake_select_lex) { - JOIN *join = new JOIN(thd, fields, select_options, result); - DBUG_ENTER("mysql_select"); - thd->proc_info="init"; - thd->used_tables=0; // Updated by setup_fields - if (join->prepare(tables, conds, order, group, having, proc_param, - select_lex, unit, fake_select_lex)) + bool free_join= 1; + JOIN *join; + if (!fake_select_lex && select_lex->join != 0) { - DBUG_RETURN(-1); + //here is EXPLAIN of subselect or derived table + join= select_lex->join; + join->result= result; + if (!join->procedure && result->prepare(join->fields_list, unit)) + { + DBUG_RETURN(-1); + } + join->select_options= select_options; + free_join= 0; } - switch (join->optimize()) { + else + { + join= new JOIN(thd, fields, select_options, result); + thd->proc_info="init"; + thd->used_tables=0; // Updated by setup_fields + + if (join->prepare(tables, conds, order, group, having, proc_param, + select_lex, unit, fake_select_lex)) + { + DBUG_RETURN(-1); + } + } + + switch (join->optimize()) + { case 1: DBUG_RETURN(join->error); case -1: goto err; - } + } - if (join->global_optimize()) + if (free_join && join->global_optimize()) goto err; join->exec(); err: - thd->limit_found_rows = join->send_records; - thd->examined_row_count = join->examined_rows; - thd->proc_info="end"; - int error= (fake_select_lex?0:join->cleanup(thd)) || thd->net.report_error; - delete join; - DBUG_RETURN(error); + if (free_join) + { + thd->limit_found_rows = join->send_records; + thd->examined_row_count = join->examined_rows; + thd->proc_info="end"; + int error= (fake_select_lex?0:join->cleanup(thd)) || thd->net.report_error; + delete join; + DBUG_RETURN(error); + } + else + DBUG_RETURN(0); } /***************************************************************************** @@ -7411,9 +7435,43 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, result->send_error(0,NullS); } } + for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit(); + unit; + unit= unit->next_unit()) + { + if (mysql_explain_union(thd, unit, result)) + DBUG_VOID_RETURN; + } DBUG_VOID_RETURN; } +int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) +{ + int res= 0; + SELECT_LEX *first= unit->first_select(); + for (SELECT_LEX *sl= first; + sl; + sl= sl->next_select()) + { + res= mysql_explain_select(thd, sl, + (((&thd->lex.select_lex)==sl)? + ((sl->next_select_in_list())?"PRIMARY": + "SIMPLE"): + ((sl == first)? + ((sl->depended)?"DEPENDENT SUBSELECT": + "SUBSELECT"): + ((sl->depended)?"DEPENDENT UNION": + "UNION"))), + result); + if (res) + break; + + } + if (res > 0) + res= -res; // mysql_explain_select do not report error + return res; +} + int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, select_result *result) { diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 01b0eb9e6ec..eaeec2c1e68 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -109,7 +109,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) if (prepared) DBUG_RETURN(0); prepared= 1; - + union_result=0; describe=(first_select()->options & SELECT_DESCRIBE) ? 1 : 0; res= 0; found_rows_for_union= false; @@ -309,10 +309,12 @@ int st_select_lex_unit::exec() int st_select_lex_unit::cleanup() { DBUG_ENTER("st_select_lex_unit::cleanup"); - delete union_result; - free_tmp_table(thd,table); - table= 0; // Safety - + if (union_result) + { + delete union_result; + free_tmp_table(thd,table); + table= 0; // Safety + } List_iterator<JOIN*> j(joins); JOIN** join; while ((join= j++)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1786d1ef93f..4f75716ff56 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -528,7 +528,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <lex_str> IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME - ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET + ULONGLONG_NUM field_ident select_alias ident ident_or_text UNDERSCORE_CHARSET %type <lex_str_ptr> opt_table_alias @@ -637,7 +637,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union union_list precision union_option opt_on_delete_item subselect_start opt_and - subselect_end + subselect_end select_var_list select_var_list_init END_OF_INPUT %type <NONE> @@ -759,7 +759,8 @@ master_def: RELAY_LOG_POS_SYM EQ ULONG_NUM { Lex->mi.relay_log_pos = $3; - }; + } + ; /* create a table */ @@ -824,11 +825,13 @@ create: LEX *lex=Lex; lex->udf.returns=(Item_result) $7; lex->udf.dl=$9.str; - }; + } + ; create2: '(' field_list ')' opt_create_table_options create3 {} - | opt_create_table_options create3 {}; + | opt_create_table_options create3 {} + ; create3: /* empty */ {} @@ -838,7 +841,8 @@ create3: lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list opt_select_from union {}; + select_options select_item_list opt_select_from union {} + ; opt_as: /* empty */ {} @@ -1549,6 +1553,7 @@ select_part2: select_into: limit_clause {} | select_from + | opt_into | opt_into select_from | select_from opt_into; @@ -2293,11 +2298,11 @@ select_part3: mysql_init_select(lex); lex->select->linkage= DERIVED_TABLE_TYPE; } - select_options select_item_list select_intoto + select_options select_item_list select_intoto; select_intoto: limit_clause {} - | select_from + | select_from; opt_outer: /* empty */ {} @@ -2548,20 +2553,61 @@ procedure_item: YYABORT; if (!$2->name) $2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); - }; + } + ; + + +select_var_list_init: + { + LEX *lex=Lex; + if (!lex->describe && (!(lex->result= new select_dumpvar()))) + YYABORT; + } + select_var_list + ; + +select_var_list: + select_var_list ',' select_var_ident + | select_var_ident {} + ; + +select_var_ident: '@' ident_or_text + { + LEX *lex=Lex; + if (lex->result && ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) + YYABORT; + } + ; opt_into: - INTO OUTFILE TEXT_STRING + INTO OUTFILE TEXT_STRING { - if (!(Lex->exchange= new sql_exchange($3.str,0))) - YYABORT; + LEX *lex=Lex; + if (!lex->describe) + { + if (!(lex->exchange= new sql_exchange($3.str,0))) + YYABORT; + if (!(lex->result= new select_export(lex->exchange))) + YYABORT; + } } opt_field_term opt_line_term | INTO DUMPFILE TEXT_STRING { - if (!(Lex->exchange= new sql_exchange($3.str,1))) - YYABORT; - }; + LEX *lex=Lex; + if (!lex->describe) + { + if (!(lex->exchange= new sql_exchange($3.str,1))) + YYABORT; + if (!(lex->result= new select_dump(lex->exchange))) + YYABORT; + } + } + | INTO select_var_list_init + { + current_thd->safe_to_cache_query=0; + } + ; /* DO statement @@ -3025,7 +3071,11 @@ describe: } opt_describe_column | describe_command select - { Lex->select_lex.options|= SELECT_DESCRIBE; }; + { + LEX *lex=Lex; + lex->select_lex.options|= SELECT_DESCRIBE; + lex->describe=1; + }; describe_command: @@ -3231,7 +3281,7 @@ param_marker: yyerror("You have an error in your SQL syntax"); YYABORT; } - } + }; literal: text_literal { $$ = $1; } | NUM { $$ = new Item_int($1.str, (longlong) atol($1.str),$1.length); } @@ -3582,7 +3632,7 @@ internal_variable_name: YYABORT; $$=tmp; } - ; + ; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -3603,7 +3653,8 @@ text_or_password: make_scrambled_password(buff,$3.str); $$=buff; } - }; + } + ; set_expr_or_default: @@ -3633,16 +3684,19 @@ table_lock_list: table_lock: table_ident opt_table_alias lock_option - { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; }; + { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; } + ; lock_option: READ_SYM { $$=TL_READ_NO_INSERT; } | WRITE_SYM { $$=current_thd->update_lock_default; } | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } - | READ_SYM LOCAL_SYM { $$= TL_READ; }; + | READ_SYM LOCAL_SYM { $$= TL_READ; } + ; unlock: - UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; }; + UNLOCK_SYM table_or_tables { Lex->sql_command=SQLCOM_UNLOCK_TABLES; } + ; /* @@ -3672,15 +3726,18 @@ handler: if (!add_table_to_list($2,0,0)) YYABORT; } - handler_read_or_scan where_clause limit_clause { }; + handler_read_or_scan where_clause limit_clause { } + ; handler_read_or_scan: handler_scan_function { Lex->backup_dir= 0; } - | ident handler_rkey_function { Lex->backup_dir= $1.str; }; + | ident handler_rkey_function { Lex->backup_dir= $1.str; } + ; handler_scan_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } - | NEXT_SYM { Lex->ha_read_mode = RNEXT; }; + | NEXT_SYM { Lex->ha_read_mode = RNEXT; } + ; handler_rkey_function: FIRST_SYM { Lex->ha_read_mode = RFIRST; } @@ -3694,14 +3751,16 @@ handler_rkey_function: lex->ha_rkey_mode=$1; if (!(lex->insert_list = new List_item)) YYABORT; - } '(' values ')' { }; + } '(' values ')' { } + ; handler_rkey_mode: EQ { $$=HA_READ_KEY_EXACT; } | GE { $$=HA_READ_KEY_OR_NEXT; } | LE { $$=HA_READ_KEY_OR_PREV; } | GT_SYM { $$=HA_READ_AFTER_KEY; } - | LT { $$=HA_READ_BEFORE_KEY; }; + | LT { $$=HA_READ_BEFORE_KEY; } + ; /* GRANT / REVOKE */ @@ -3739,7 +3798,8 @@ grant: grant_privileges: grant_privilege_list {} | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;} - | ALL { Lex->grant = GLOBAL_ACLS;}; + | ALL { Lex->grant = GLOBAL_ACLS;} + ; grant_privilege_list: grant_privilege @@ -3858,7 +3918,8 @@ opt_table: YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; - }; + } + ; user_list: @@ -3889,7 +3950,8 @@ grant_user: | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING { $$=$1; $1->password=$5 ; } | user - { $$=$1; $1->password.str=NullS; }; + { $$=$1; $1->password.str=NullS; } + ; opt_column_list: @@ -3922,7 +3984,8 @@ column_list_id: point->rights |= lex->which_columns; else lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); - }; + } + ; require_clause: /* empty */ @@ -3942,7 +4005,7 @@ require_clause: /* empty */ { Lex->ssl_type=SSL_TYPE_NONE; } - ; + ; grant_options: /* empty */ {} @@ -3950,7 +4013,8 @@ grant_options: grant_option_list: grant_option_list grant_option {} - | grant_option {}; + | grant_option {} + ; grant_option: GRANT OPTION { Lex->grant |= GRANT_ACL;} @@ -3968,14 +4032,16 @@ grant_option: { Lex->mqh.connections=$2; Lex->mqh.bits |= 4; - }; + } + ; begin: BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work; opt_work: /* empty */ {} - | WORK_SYM {;}; + | WORK_SYM {;} + ; commit: COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; @@ -4085,4 +4151,4 @@ subselect_end: { LEX *lex=Lex; lex->select = lex->select->outer_select(); - } + }; |