some fixes for SELECT INTO @vars ..

parent 51e98da2
...@@ -916,31 +916,41 @@ bool select_exists_subselect::send_data(List<Item> &items) ...@@ -916,31 +916,41 @@ bool select_exists_subselect::send_data(List<Item> &items)
/*************************************************************************** /***************************************************************************
** Dump of select to variables ** Dump of select to variables
***************************************************************************/ ***************************************************************************/
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
bool select_dumpvar::send_data(List<Item> &items)
{ {
List_iterator_fast<Item> li(items); List_iterator_fast<Item> li(list);
List_iterator_fast<LEX_STRING> gl(current_thd->lex.select_into_var_list); List_iterator_fast<LEX_STRING> gl(var_list);
Item *item; Item *item;
LEX_STRING *ls; LEX_STRING *ls;
DBUG_ENTER("send_data"); if (var_list.elements != list.elements)
if (row_count++ > 1)
{ {
my_error(ER_TOO_MANY_ROWS, MYF(0)); my_error(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, MYF(0));
goto err; 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); 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_fields(current_thd,(TABLE_LIST*) current_thd->lex.select_lex.table_list.first,&item);
xx->fix_length_and_dec(); xx->fix_length_and_dec();
xx->update(); vars.push_back(xx);
} }
DBUG_RETURN(0); return 0;
err: }
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); DBUG_RETURN(1);
}
while ((xx=li++))
xx->update();
DBUG_RETURN(0);
} }
bool select_dumpvar::send_eof() bool select_dumpvar::send_eof()
......
...@@ -969,22 +969,12 @@ public: ...@@ -969,22 +969,12 @@ public:
class select_dumpvar :public select_result { class select_dumpvar :public select_result {
ha_rows row_count; ha_rows row_count;
public: public:
select_dumpvar(void) { row_count=0;} 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() {} ~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u) { return 0;} int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
bool send_fields(List<Item> &list, uint flag) bool send_fields(List<Item> &list, uint flag) {return 0;}
{
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<Item> &items); bool send_data(List<Item> &items);
void send_error(uint errcode,const char *err)
{
my_message(errcode, err, MYF(0));
}
bool send_eof(); bool send_eof();
}; };
...@@ -334,6 +334,7 @@ typedef struct st_lex ...@@ -334,6 +334,7 @@ typedef struct st_lex
enum SSL_type ssl_type; /* defined in violite.h */ enum SSL_type ssl_type; /* defined in violite.h */
String *wild; String *wild;
sql_exchange *exchange; sql_exchange *exchange;
select_result *result;
List<key_part_spec> col_list; List<key_part_spec> col_list;
List<key_part_spec> ref_list; List<key_part_spec> ref_list;
...@@ -348,7 +349,6 @@ typedef struct st_lex ...@@ -348,7 +349,6 @@ typedef struct st_lex
List<List_item> many_values; List<List_item> many_values;
List<set_var_base> var_list; List<set_var_base> var_list;
List<Item> param_list; List<Item> param_list;
List<LEX_STRING> select_into_var_list;
SQL_LIST proc_list, auxilliary_table_list; SQL_LIST proc_list, auxilliary_table_list;
TYPELIB *interval; TYPELIB *interval;
create_field *last_field; create_field *last_field;
......
...@@ -1403,7 +1403,7 @@ mysql_execute_command(THD *thd) ...@@ -1403,7 +1403,7 @@ mysql_execute_command(THD *thd)
switch (lex->sql_command) { switch (lex->sql_command) {
case SQLCOM_SELECT: case SQLCOM_SELECT:
{ {
select_result *result; select_result *result=lex->result;
if (select_lex->options & SELECT_DESCRIBE) if (select_lex->options & SELECT_DESCRIBE)
lex->exchange=0; lex->exchange=0;
if (tables) if (tables)
...@@ -1430,36 +1430,20 @@ mysql_execute_command(THD *thd) ...@@ -1430,36 +1430,20 @@ mysql_execute_command(THD *thd)
if (unit->select_limit_cnt == HA_POS_ERROR) if (unit->select_limit_cnt == HA_POS_ERROR)
select_lex->options&= ~OPTION_FOUND_ROWS; 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; if ((result=new select_send()))
break;
}
}
}
else if (lex->select_into_var_list.elements)
{ {
if (!(result=new select_dumpvar())) /*
{ Normal select:
res= -1; Change lock if we are using SELECT HIGH PRIORITY,
break; FOR UPDATE or IN SHARE MODE
} */
TABLE_LIST *table;
for (table = tables ; table ; table=table->next)
table->lock_type= lex->lock_option;
} }
else else
{
if (!(result=new select_send()))
{ {
res= -1; res= -1;
#ifdef DELETE_ITEMS #ifdef DELETE_ITEMS
...@@ -1468,17 +1452,6 @@ mysql_execute_command(THD *thd) ...@@ -1468,17 +1452,6 @@ mysql_execute_command(THD *thd)
#endif #endif
break; 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 (!(res=open_and_lock_tables(thd,tables)))
...@@ -2976,8 +2949,8 @@ mysql_init_select(LEX *lex) ...@@ -2976,8 +2949,8 @@ mysql_init_select(LEX *lex)
lex->thd->variables.select_limit; lex->thd->variables.select_limit;
select_lex->olap= UNSPECIFIED_OLAP_TYPE; select_lex->olap= UNSPECIFIED_OLAP_TYPE;
lex->exchange= 0; lex->exchange= 0;
lex->result= 0;
lex->proc_list.first= 0; lex->proc_list.first= 0;
lex->select_into_var_list.empty();
} }
......
...@@ -632,7 +632,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -632,7 +632,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild union union_list single_multi table_wild_list table_wild_one opt_wild union union_list
precision union_option opt_on_delete_item subselect_start opt_and 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 END_OF_INPUT
%type <NONE> %type <NONE>
...@@ -754,7 +754,8 @@ master_def: ...@@ -754,7 +754,8 @@ master_def:
RELAY_LOG_POS_SYM EQ ULONG_NUM RELAY_LOG_POS_SYM EQ ULONG_NUM
{ {
Lex->mi.relay_log_pos = $3; Lex->mi.relay_log_pos = $3;
}; }
;
/* create a table */ /* create a table */
...@@ -819,11 +820,13 @@ create: ...@@ -819,11 +820,13 @@ create:
LEX *lex=Lex; LEX *lex=Lex;
lex->udf.returns=(Item_result) $7; lex->udf.returns=(Item_result) $7;
lex->udf.dl=$9.str; lex->udf.dl=$9.str;
}; }
;
create2: create2:
'(' field_list ')' opt_create_table_options create3 {} '(' field_list ')' opt_create_table_options create3 {}
| opt_create_table_options create3 {}; | opt_create_table_options create3 {}
;
create3: create3:
/* empty */ {} /* empty */ {}
...@@ -833,7 +836,8 @@ create3: ...@@ -833,7 +836,8 @@ create3:
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
mysql_init_select(lex); mysql_init_select(lex);
} }
select_options select_item_list opt_select_from union {}; select_options select_item_list opt_select_from union {}
;
opt_as: opt_as:
/* empty */ {} /* empty */ {}
...@@ -2543,36 +2547,53 @@ procedure_item: ...@@ -2543,36 +2547,53 @@ procedure_item:
YYABORT; YYABORT;
if (!$2->name) if (!$2->name)
$2->set_name($1,(uint) ((char*) Lex->tok_end - $1)); $2->set_name($1,(uint) ((char*) Lex->tok_end - $1));
}; }
;
select_var_list:
select_var_list ',' '@' ident_or_text select_var_list_init:
{ {
if (Lex->select_into_var_list.push_back((LEX_STRING*) sql_memdup(&$4,sizeof(LEX_STRING)))) if (!(Lex->result= new select_dumpvar()))
YYABORT; YYABORT;
} }
| '@' ident_or_text select_var_list
;
select_var_list:
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(&$2,sizeof(LEX_STRING)))) LEX *lex=Lex;
if ( ((select_dumpvar *)lex->result)->var_list.push_back((LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING))))
YYABORT; YYABORT;
}; }
opt_into: opt_into:
INTO OUTFILE TEXT_STRING 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; YYABORT;
} }
opt_field_term opt_line_term opt_field_term opt_line_term
| INTO DUMPFILE TEXT_STRING | 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; YYABORT;
} }
| INTO select_var_list | INTO select_var_list_init
{ {
current_thd->safe_to_cache_query=0; current_thd->safe_to_cache_query=0;
}; }
;
/* /*
DO statement DO statement
...@@ -3582,7 +3603,8 @@ option_value: ...@@ -3582,7 +3603,8 @@ option_value:
| PASSWORD FOR_SYM user equal text_or_password | PASSWORD FOR_SYM user equal text_or_password
{ {
Lex->var_list.push_back(new set_var_password($3,$5)); Lex->var_list.push_back(new set_var_password($3,$5));
}; }
;
internal_variable_name: internal_variable_name:
ident ident
...@@ -3591,7 +3613,8 @@ internal_variable_name: ...@@ -3591,7 +3613,8 @@ internal_variable_name:
if (!tmp) if (!tmp)
YYABORT; YYABORT;
$$=tmp; $$=tmp;
}; }
;
isolation_types: isolation_types:
READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
...@@ -3612,7 +3635,8 @@ text_or_password: ...@@ -3612,7 +3635,8 @@ text_or_password:
make_scrambled_password(buff,$3.str); make_scrambled_password(buff,$3.str);
$$=buff; $$=buff;
} }
}; }
;
set_expr_or_default: set_expr_or_default:
...@@ -3642,16 +3666,19 @@ table_lock_list: ...@@ -3642,16 +3666,19 @@ table_lock_list:
table_lock: table_lock:
table_ident opt_table_alias lock_option 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: lock_option:
READ_SYM { $$=TL_READ_NO_INSERT; } READ_SYM { $$=TL_READ_NO_INSERT; }
| WRITE_SYM { $$=current_thd->update_lock_default; } | WRITE_SYM { $$=current_thd->update_lock_default; }
| LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; }
| READ_SYM LOCAL_SYM { $$= TL_READ; }; | READ_SYM LOCAL_SYM { $$= TL_READ; }
;
unlock: 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: ...@@ -3681,15 +3708,18 @@ handler:
if (!add_table_to_list($2,0,0)) if (!add_table_to_list($2,0,0))
YYABORT; YYABORT;
} }
handler_read_or_scan where_clause limit_clause { }; handler_read_or_scan where_clause limit_clause { }
;
handler_read_or_scan: handler_read_or_scan:
handler_scan_function { Lex->backup_dir= 0; } 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: handler_scan_function:
FIRST_SYM { Lex->ha_read_mode = RFIRST; } FIRST_SYM { Lex->ha_read_mode = RFIRST; }
| NEXT_SYM { Lex->ha_read_mode = RNEXT; }; | NEXT_SYM { Lex->ha_read_mode = RNEXT; }
;
handler_rkey_function: handler_rkey_function:
FIRST_SYM { Lex->ha_read_mode = RFIRST; } FIRST_SYM { Lex->ha_read_mode = RFIRST; }
...@@ -3703,14 +3733,16 @@ handler_rkey_function: ...@@ -3703,14 +3733,16 @@ handler_rkey_function:
lex->ha_rkey_mode=$1; lex->ha_rkey_mode=$1;
if (!(lex->insert_list = new List_item)) if (!(lex->insert_list = new List_item))
YYABORT; YYABORT;
} '(' values ')' { }; } '(' values ')' { }
;
handler_rkey_mode: handler_rkey_mode:
EQ { $$=HA_READ_KEY_EXACT; } EQ { $$=HA_READ_KEY_EXACT; }
| GE { $$=HA_READ_KEY_OR_NEXT; } | GE { $$=HA_READ_KEY_OR_NEXT; }
| LE { $$=HA_READ_KEY_OR_PREV; } | LE { $$=HA_READ_KEY_OR_PREV; }
| GT_SYM { $$=HA_READ_AFTER_KEY; } | GT_SYM { $$=HA_READ_AFTER_KEY; }
| LT { $$=HA_READ_BEFORE_KEY; }; | LT { $$=HA_READ_BEFORE_KEY; }
;
/* GRANT / REVOKE */ /* GRANT / REVOKE */
...@@ -3748,7 +3780,8 @@ grant: ...@@ -3748,7 +3780,8 @@ grant:
grant_privileges: grant_privileges:
grant_privilege_list {} grant_privilege_list {}
| ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;} | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;}
| ALL { Lex->grant = GLOBAL_ACLS;}; | ALL { Lex->grant = GLOBAL_ACLS;}
;
grant_privilege_list: grant_privilege_list:
grant_privilege grant_privilege
...@@ -3867,7 +3900,8 @@ opt_table: ...@@ -3867,7 +3900,8 @@ opt_table:
YYABORT; YYABORT;
if (lex->grant == GLOBAL_ACLS) if (lex->grant == GLOBAL_ACLS)
lex->grant = TABLE_ACLS & ~GRANT_ACL; lex->grant = TABLE_ACLS & ~GRANT_ACL;
}; }
;
user_list: user_list:
...@@ -3898,7 +3932,8 @@ grant_user: ...@@ -3898,7 +3932,8 @@ grant_user:
| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
{ $$=$1; $1->password=$5 ; } { $$=$1; $1->password=$5 ; }
| user | user
{ $$=$1; $1->password.str=NullS; }; { $$=$1; $1->password.str=NullS; }
;
opt_column_list: opt_column_list:
...@@ -3931,7 +3966,8 @@ column_list_id: ...@@ -3931,7 +3966,8 @@ column_list_id:
point->rights |= lex->which_columns; point->rights |= lex->which_columns;
else else
lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns));
}; }
;
require_clause: /* empty */ require_clause: /* empty */
...@@ -3950,7 +3986,8 @@ require_clause: /* empty */ ...@@ -3950,7 +3986,8 @@ require_clause: /* empty */
| REQUIRE_SYM NONE_SYM | REQUIRE_SYM NONE_SYM
{ {
Lex->ssl_type=SSL_TYPE_NONE; Lex->ssl_type=SSL_TYPE_NONE;
}; }
;
grant_options: grant_options:
/* empty */ {} /* empty */ {}
...@@ -3958,7 +3995,8 @@ grant_options: ...@@ -3958,7 +3995,8 @@ grant_options:
grant_option_list: grant_option_list:
grant_option_list grant_option {} grant_option_list grant_option {}
| grant_option {}; | grant_option {}
;
grant_option: grant_option:
GRANT OPTION { Lex->grant |= GRANT_ACL;} GRANT OPTION { Lex->grant |= GRANT_ACL;}
...@@ -3976,14 +4014,16 @@ grant_option: ...@@ -3976,14 +4014,16 @@ grant_option:
{ {
Lex->mqh.connections=$2; Lex->mqh.connections=$2;
Lex->mqh.bits |= 4; Lex->mqh.bits |= 4;
}; }
;
begin: begin:
BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work; BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work;
opt_work: opt_work:
/* empty */ {} /* empty */ {}
| WORK_SYM {;}; | WORK_SYM {;}
;
commit: commit:
COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;};
......
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