From 97990887cb5b6fb6107ab123933b5ddc0f970633 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Fri, 11 Oct 2002 21:49:10 +0300 Subject: [PATCH 1/6] SCRUM task --- mysql-test/r/select.result | 10 +++++++++ mysql-test/t/select.test | 4 ++++ sql/sql_class.cc | 44 ++++++++++++++++++++++++++++++++++++++ sql/sql_class.h | 22 +++++++++++++++++++ sql/sql_lex.h | 1 + sql/sql_parse.cc | 44 ++++++++++++++++++++++++-------------- sql/sql_yacc.yy | 37 +++++++++++++++++++++++--------- 7 files changed, 136 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index fc918012d1f..c4fac8d8e7f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3266,3 +3266,13 @@ 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 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 94806d44e37..57a17e40723 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1751,3 +1751,7 @@ 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; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 648e05c1610..02c98c87c4e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -907,3 +907,47 @@ bool select_exists_subselect::send_data(List &items) DBUG_RETURN(0); } + +/*************************************************************************** +** Dump of select to variables +***************************************************************************/ + + +bool select_dumpvar::send_data(List &items) +{ + List_iterator_fast li(items); + List_iterator_fast gl(current_thd->lex.select_into_var_list); + Item *item; + LEX_STRING *ls; + DBUG_ENTER("send_data"); + + if (row_count++ > 1) + { + my_error(ER_TOO_MANY_ROWS, MYF(0)); + goto err; + } + 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(); + xx->update(); + } + DBUG_RETURN(0); +err: + DBUG_RETURN(1); +} + +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..cc01344c8de 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -966,3 +966,25 @@ public: bool send_eof(); }; +class select_dumpvar :public select_result { + ha_rows row_count; +public: + select_dumpvar(void) { row_count=0;} + ~select_dumpvar() {} + int prepare(List &list, SELECT_LEX_UNIT *u) { return 0;} + bool send_fields(List &list, uint flag) + { + if (current_thd->lex.select_into_var_list.elements != list.elements) + { + my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); + return 1; + } + return 0; + } + bool send_data(List &items); + void send_error(uint errcode,const char *err) + { + my_message(errcode, err, MYF(0)); + } + bool send_eof(); +}; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index acf73f34d5d..f618d9b7219 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -347,6 +347,7 @@ typedef struct st_lex List many_values; List var_list; List param_list; + List select_into_var_list; SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7902e66043d..e1049988a83 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1449,25 +1449,36 @@ mysql_execute_command(THD *thd) } } } - else if (!(result=new select_send())) + else if (lex->select_into_var_list.elements) { - res= -1; -#ifdef DELETE_ITEMS - delete select_lex->having; - delete select_lex->where; -#endif - break; + if (!(result=new select_dumpvar())) + { + res= -1; + break; + } } - else + 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 (!(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))) @@ -2966,6 +2977,7 @@ mysql_init_select(LEX *lex) select_lex->olap= UNSPECIFIED_OLAP_TYPE; lex->exchange= 0; lex->proc_list.first= 0; + lex->select_into_var_list.empty(); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f7ab07b2da3..5d77e887bd1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -523,7 +523,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type 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 opt_table_alias @@ -632,7 +632,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 END_OF_INPUT %type @@ -1544,6 +1544,7 @@ select_part2: select_into: limit_clause {} | select_from + | opt_into | opt_into select_from | select_from opt_into; @@ -2287,11 +2288,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 */ {} @@ -2544,8 +2545,20 @@ procedure_item: $2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); }; +select_var_list: + select_var_list ',' '@' ident_or_text + { + if (Lex->select_into_var_list.push_back((LEX_STRING*) sql_memdup(&$4,sizeof(LEX_STRING)))) + YYABORT; + } + | '@' ident_or_text + { + if (Lex->select_into_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; @@ -2555,6 +2568,10 @@ opt_into: { if (!(Lex->exchange= new sql_exchange($3.str,1))) YYABORT; + } + | INTO select_var_list + { + current_thd->safe_to_cache_query=0; }; /* @@ -3225,7 +3242,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); } @@ -3565,7 +3582,7 @@ option_value: | PASSWORD FOR_SYM user equal text_or_password { Lex->var_list.push_back(new set_var_password($3,$5)); - } + }; internal_variable_name: ident @@ -3574,7 +3591,7 @@ internal_variable_name: if (!tmp) YYABORT; $$=tmp; - } + }; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -3933,7 +3950,7 @@ require_clause: /* empty */ | REQUIRE_SYM NONE_SYM { Lex->ssl_type=SSL_TYPE_NONE; - } + }; grant_options: /* empty */ {} @@ -4076,4 +4093,4 @@ subselect_end: { LEX *lex=Lex; lex->select = lex->select->outer_select(); - } + }; From 21dd4a4dd53a2ef9ca4898bcd77172d3895e5398 Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 16 Oct 2002 00:42:59 +0300 Subject: [PATCH 2/6] fixed subselect explain bug --- mysql-test/r/subselect.result | 24 +++++++-- mysql-test/t/subselect.test | 20 ++++++-- sql/mysql_priv.h | 2 + sql/sql_lex.cc | 2 +- sql/sql_parse.cc | 19 +------ sql/sql_select.cc | 94 ++++++++++++++++++++++++++++------- 6 files changed, 116 insertions(+), 45 deletions(-) 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 &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_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_parse.cc b/sql/sql_parse.cc index 7902e66043d..bb2fe838546 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1484,24 +1484,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(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f7d585e85f8..ac5f922d3a3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -213,7 +213,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; @@ -348,7 +348,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) @@ -1018,36 +1018,60 @@ mysql_select(THD *thd, TABLE_LIST *tables, List &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); } /***************************************************************************** @@ -7366,9 +7390,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) { From 73f61b9173a2dbfc3199065aaa52e77a2052a5b2 Mon Sep 17 00:00:00 2001 From: "arjen@fred.bitbike.com" <> Date: Wed, 16 Oct 2002 08:07:41 +1000 Subject: [PATCH 3/6] Name fix. --- Docs/world.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Docs/world.sql b/Docs/world.sql index 7ddd3787ec6..f253819da2e 100644 --- a/Docs/world.sql +++ b/Docs/world.sql @@ -4334,7 +4334,7 @@ INSERT INTO Country VALUES ('SWZ','Swaziland','Africa','Southern Africa',17364.0 INSERT INTO Country VALUES ('CHE','Switzerland','Europe','Western Europe',41284.00,1499,7160400,79.6,264478.00,256092.00,'Schweiz/Suisse/Svizzera/Svizra','Federation','Adolf Ogi',3248,'CH'); INSERT INTO Country VALUES ('SYR','Syria','Asia','Middle East',185180.00,1941,16125000,68.5,65984.00,64926.00,'Suriya','Republic','Bashar al-Assad',3250,'SY'); INSERT INTO Country VALUES ('TJK','Tajikistan','Asia','Southern and Central Asia',143100.00,1991,6188000,64.1,1990.00,1056.00,'Toçikiston','Republic','Emomali Rahmonov',3261,'TJ'); -INSERT INTO Country VALUES ('TWN','Taiwan, Province of China','Asia','Eastern Asia',36188.00,1945,22256000,76.4,256254.00,263451.00,'T’ai-wan','Republic','Chen Shui-bian',3263,'TW'); +INSERT INTO Country VALUES ('TWN','Taiwan','Asia','Eastern Asia',36188.00,1945,22256000,76.4,256254.00,263451.00,'T’ai-wan','Republic','Chen Shui-bian',3263,'TW'); INSERT INTO Country VALUES ('TZA','Tanzania','Africa','Eastern Africa',883749.00,1961,33517000,52.3,8005.00,7388.00,'Tanzania','Republic','Benjamin William Mkapa',3306,'TZ'); INSERT INTO Country VALUES ('DNK','Denmark','Europe','Nordic Countries',43094.00,800,5330000,76.5,174099.00,169264.00,'Danmark','Constitutional Monarchy','Margrethe II',3315,'DK'); INSERT INTO Country VALUES ('THA','Thailand','Asia','Southeast Asia',513115.00,1350,61399000,68.6,116416.00,153907.00,'Prathet Thai','Constitutional Monarchy','Bhumibol Adulyadej',3320,'TH'); From cd5ff6301ed68b253ccffbb10e70ff3b80ded7cf Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 16 Oct 2002 16:55:08 +0300 Subject: [PATCH 4/6] some fixes for SELECT INTO @vars .. --- sql/sql_class.cc | 38 ++++++++++------ sql/sql_class.h | 20 +++------ sql/sql_lex.h | 2 +- sql/sql_parse.cc | 53 ++++++---------------- sql/sql_yacc.yy | 112 ++++++++++++++++++++++++++++++++--------------- 5 files changed, 119 insertions(+), 106 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a1689feb754..083b0ed2543 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -916,31 +916,41 @@ bool select_exists_subselect::send_data(List &items) /*************************************************************************** ** Dump of select to variables ***************************************************************************/ - - -bool select_dumpvar::send_data(List &items) +int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { - List_iterator_fast li(items); - List_iterator_fast gl(current_thd->lex.select_into_var_list); + List_iterator_fast li(list); + List_iterator_fast gl(var_list); Item *item; LEX_STRING *ls; - DBUG_ENTER("send_data"); - - if (row_count++ > 1) + if (var_list.elements != list.elements) { - my_error(ER_TOO_MANY_ROWS, MYF(0)); - goto err; + my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); + return 1; } - while ((item=li++) && (ls=gl++)) + 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(); - xx->update(); + vars.push_back(xx); } + return 0; +} +bool select_dumpvar::send_data(List &items) +{ + List_iterator_fast 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); -err: - DBUG_RETURN(1); } bool select_dumpvar::send_eof() diff --git a/sql/sql_class.h b/sql/sql_class.h index cc01344c8de..7b5a6da8c6b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -969,22 +969,12 @@ public: class select_dumpvar :public select_result { ha_rows row_count; public: - select_dumpvar(void) { row_count=0;} + List var_list; + List vars; + select_dumpvar(void) { var_list.empty(); vars.empty(); row_count=0;} ~select_dumpvar() {} - int prepare(List &list, SELECT_LEX_UNIT *u) { return 0;} - bool send_fields(List &list, uint flag) - { - if (current_thd->lex.select_into_var_list.elements != list.elements) - { - my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0)); - return 1; - } - return 0; - } + int prepare(List &list, SELECT_LEX_UNIT *u); + bool send_fields(List &list, uint flag) {return 0;} bool send_data(List &items); - void send_error(uint errcode,const char *err) - { - my_message(errcode, err, MYF(0)); - } bool send_eof(); }; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a0bd52a4e6a..51b1b88f24a 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 col_list; List ref_list; @@ -348,7 +349,6 @@ typedef struct st_lex List many_values; List var_list; List param_list; - List select_into_var_list; SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e1049988a83..135fb14043b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1403,7 +1403,7 @@ mysql_execute_command(THD *thd) switch (lex->sql_command) { case SQLCOM_SELECT: { - select_result *result; + select_result *result=lex->result; if (select_lex->options & SELECT_DESCRIBE) lex->exchange=0; if (tables) @@ -1430,45 +1430,9 @@ mysql_execute_command(THD *thd) if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; - if (lex->exchange) + if (!result) { - 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 (lex->select_into_var_list.elements) - { - if (!(result=new select_dumpvar())) - { - 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 + if ((result=new select_send())) { /* Normal select: @@ -1479,6 +1443,15 @@ mysql_execute_command(THD *thd) 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; + } } if (!(res=open_and_lock_tables(thd,tables))) @@ -2976,8 +2949,8 @@ 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; - lex->select_into_var_list.empty(); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5d77e887bd1..1aea8f590f1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -632,7 +632,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 select_var_list + subselect_end select_var_list select_var_list_init END_OF_INPUT %type @@ -754,7 +754,8 @@ master_def: RELAY_LOG_POS_SYM EQ ULONG_NUM { Lex->mi.relay_log_pos = $3; - }; + } + ; /* create a table */ @@ -819,11 +820,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 */ {} @@ -833,7 +836,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 */ {} @@ -2543,36 +2547,53 @@ procedure_item: YYABORT; if (!$2->name) $2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); - }; + } + ; + + +select_var_list_init: + { + if (!(Lex->result= new select_dumpvar())) + YYABORT; + } + select_var_list + ; select_var_list: - select_var_list ',' '@' ident_or_text + select_var_list ',' select_var_ident + | select_var_ident {} + ; + +select_var_ident: '@' ident_or_text { - if (Lex->select_into_var_list.push_back((LEX_STRING*) sql_memdup(&$4,sizeof(LEX_STRING)))) + LEX *lex=Lex; + if ( ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) YYABORT; } - | '@' ident_or_text - { - if (Lex->select_into_var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) - YYABORT; - }; opt_into: INTO OUTFILE TEXT_STRING { - if (!(Lex->exchange= new sql_exchange($3.str,0))) + LEX *lex=Lex; + 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))) + LEX *lex=Lex; + if (!(lex->exchange= new sql_exchange($3.str,1))) YYABORT; + if (!(lex->result= new select_dump(lex->exchange))) + YYABORT; } - | INTO select_var_list + | INTO select_var_list_init { current_thd->safe_to_cache_query=0; - }; + } + ; /* DO statement @@ -3582,7 +3603,8 @@ option_value: | PASSWORD FOR_SYM user equal text_or_password { Lex->var_list.push_back(new set_var_password($3,$5)); - }; + } + ; internal_variable_name: ident @@ -3591,7 +3613,8 @@ internal_variable_name: if (!tmp) YYABORT; $$=tmp; - }; + } + ; isolation_types: READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } @@ -3612,7 +3635,8 @@ text_or_password: make_scrambled_password(buff,$3.str); $$=buff; } - }; + } + ; set_expr_or_default: @@ -3642,16 +3666,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; } + ; /* @@ -3681,15 +3708,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; } @@ -3703,14 +3733,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 */ @@ -3748,7 +3780,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 @@ -3867,7 +3900,8 @@ opt_table: YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; - }; + } + ; user_list: @@ -3898,7 +3932,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: @@ -3931,7 +3966,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 */ @@ -3950,7 +3986,8 @@ require_clause: /* empty */ | REQUIRE_SYM NONE_SYM { Lex->ssl_type=SSL_TYPE_NONE; - }; + } + ; grant_options: /* empty */ {} @@ -3958,7 +3995,8 @@ grant_options: grant_option_list: grant_option_list grant_option {} - | grant_option {}; + | grant_option {} + ; grant_option: GRANT OPTION { Lex->grant |= GRANT_ACL;} @@ -3976,14 +4014,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;}; From 6561faa10e8dbc24eedb1d8574053f5f23790ca8 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 16 Oct 2002 21:17:57 +0300 Subject: [PATCH 5/6] Some small accelerations ... I intend to do some more accelerations in mysql_execute_command and in SQLCOM_SELECT part for which I need to fix EXPLAIN with derived tables plus few additional items. If this proves to be much I wil just make it a new SCRUM task --- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 59 +++++++++++++++++++++--------------------------- sql/sql_yacc.yy | 34 +++++++++++++++++++--------- 3 files changed, 50 insertions(+), 45 deletions(-) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 28d6d93e194..de57e9f77a8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -378,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 ed8d4112410..310846f2ffe 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())) { @@ -1405,8 +1404,6 @@ mysql_execute_command(THD *thd) case SQLCOM_SELECT: { select_result *result=lex->result; - if (select_lex->options & SELECT_DESCRIBE) - lex->exchange=0; if (tables) { res=check_table_access(thd, @@ -1431,35 +1428,10 @@ mysql_execute_command(THD *thd) if (unit->select_limit_cnt == HA_POS_ERROR) select_lex->options&= ~OPTION_FOUND_ROWS; - 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; - } - } - 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())) { @@ -1477,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: @@ -2913,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 diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1aea8f590f1..a81561b70c0 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2553,7 +2553,8 @@ procedure_item: select_var_list_init: { - if (!(Lex->result= new select_dumpvar())) + LEX *lex=Lex; + if (!lex->describe && (!(lex->result= new select_dumpvar()))) YYABORT; } select_var_list @@ -2567,27 +2568,34 @@ select_var_list: select_var_ident: '@' ident_or_text { LEX *lex=Lex; - if ( ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)))) + 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 { LEX *lex=Lex; - if (!(lex->exchange= new sql_exchange($3.str,0))) - YYABORT; - if (!(lex->result= new select_export(lex->exchange))) - YYABORT; + 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 { LEX *lex=Lex; - if (!(lex->exchange= new sql_exchange($3.str,1))) - YYABORT; - if (!(lex->result= new select_dump(lex->exchange))) - YYABORT; + 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 { @@ -3057,7 +3065,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: From 0a242026a87a7bf271716fe281faff05d15805ad Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 16 Oct 2002 22:27:47 +0300 Subject: [PATCH 6/6] fix of the small bug in UNION's --- mysql-test/r/heap_btree.result | 2 +- sql/sql_union.cc | 12 +++++++----- 2 files changed, 8 insertions(+), 6 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/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 j(joins); JOIN** join; while ((join= j++))