Commit 7dc19616 authored by unknown's avatar unknown

INSERT ... UPDATE syntax (syntax only)

sql_yacc.yy and sql_parse.cc cleanup


sql/lex.h:
  INSERT ... UPDATE syntax
sql/sql_parse.cc:
  merged SQLCOM_REPLACE and SQLCOM_INSERT the same way their _SELECT counterparts were merged long time ago - just to remove duplicate code and be consistent :)
  now nobody needs SQLCOM_REPLACE* at all :))
sql/sql_yacc.yy:
  INSERT ... UPDATE syntax
  cleanup
parent c293be65
...@@ -135,6 +135,7 @@ static SYMBOL symbols[] = { ...@@ -135,6 +135,7 @@ static SYMBOL symbols[] = {
{ "DROP", SYM(DROP),0,0}, { "DROP", SYM(DROP),0,0},
{ "DUMPFILE", SYM(DUMPFILE),0,0}, { "DUMPFILE", SYM(DUMPFILE),0,0},
{ "DYNAMIC", SYM(DYNAMIC_SYM),0,0}, { "DYNAMIC", SYM(DYNAMIC_SYM),0,0},
{ "DUPLICATE", SYM(DUPLICATE),0,0},
{ "ERRORS", SYM(ERRORS),0,0}, { "ERRORS", SYM(ERRORS),0,0},
{ "END", SYM(END),0,0}, { "END", SYM(END),0,0},
{ "ELSE", SYM(ELSE),0,0}, { "ELSE", SYM(ELSE),0,0},
...@@ -342,7 +343,7 @@ static SYMBOL symbols[] = { ...@@ -342,7 +343,7 @@ static SYMBOL symbols[] = {
{ "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0}, { "SQL_CALC_FOUND_ROWS", SYM(SQL_CALC_FOUND_ROWS),0,0},
{ "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0}, { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
{ "SQL_THREAD", SYM(SQL_THREAD),0,0}, { "SQL_THREAD", SYM(SQL_THREAD),0,0},
{ "SSL", SYM(SSL_SYM),0,0}, { "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0}, { "START", SYM(START_SYM),0,0},
......
...@@ -1905,7 +1905,7 @@ mysql_execute_command(THD *thd) ...@@ -1905,7 +1905,7 @@ mysql_execute_command(THD *thd)
select_lex->select_limit, select_lex->select_limit,
lex->duplicates); lex->duplicates);
} }
else else
{ {
multi_update *result; multi_update *result;
uint table_count; uint table_count;
...@@ -1932,8 +1932,8 @@ mysql_execute_command(THD *thd) ...@@ -1932,8 +1932,8 @@ mysql_execute_command(THD *thd)
if ((res=open_and_lock_tables(thd,tables))) if ((res=open_and_lock_tables(thd,tables)))
break; break;
unit->select_limit_cnt= HA_POS_ERROR; unit->select_limit_cnt= HA_POS_ERROR;
if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) && if (!setup_fields(thd,tables,select_lex->item_list,1,0,0) &&
!setup_fields(thd,tables,lex->value_list,0,0,0) && !setup_fields(thd,tables,lex->value_list,0,0,0) &&
!thd->fatal_error && !thd->fatal_error &&
(result=new multi_update(thd,tables,select_lex->item_list, (result=new multi_update(thd,tables,select_lex->item_list,
lex->duplicates, table_count))) lex->duplicates, table_count)))
...@@ -1946,7 +1946,7 @@ mysql_execute_command(THD *thd) ...@@ -1946,7 +1946,7 @@ mysql_execute_command(THD *thd)
total_list.push_back(item); total_list.push_back(item);
while ((item=value_list++)) while ((item=value_list++))
total_list.push_back(item); total_list.push_back(item);
res= mysql_select(thd, tables, total_list, res= mysql_select(thd, tables, total_list,
select_lex->where, select_lex->where,
(ORDER *)NULL, (ORDER *)NULL, (Item *)NULL, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
...@@ -1960,26 +1960,20 @@ mysql_execute_command(THD *thd) ...@@ -1960,26 +1960,20 @@ mysql_execute_command(THD *thd)
res= -1; // Error is not sent res= -1; // Error is not sent
close_thread_tables(thd); close_thread_tables(thd);
} }
break;
case SQLCOM_INSERT:
if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INSERT_ACL,tables))
goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
lex->duplicates);
break; break;
case SQLCOM_REPLACE: case SQLCOM_REPLACE:
if (check_access(thd,INSERT_ACL | DELETE_ACL, case SQLCOM_INSERT:
tables->db,&tables->grant.privilege)) {
ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL | DELETE_ACL : INSERT_ACL);
if (check_access(thd,privilege,tables->db,&tables->grant.privilege))
goto error; /* purecov: inspected */ goto error; /* purecov: inspected */
if (grant_option && check_grant(thd,INSERT_ACL | DELETE_ACL, if (grant_option && check_grant(thd,privilege,tables))
tables))
goto error; goto error;
res = mysql_insert(thd,tables,lex->field_list,lex->many_values, res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
DUP_REPLACE); lex->duplicates);
break; break;
}
case SQLCOM_REPLACE_SELECT: case SQLCOM_REPLACE_SELECT:
case SQLCOM_INSERT_SELECT: case SQLCOM_INSERT_SELECT:
{ {
...@@ -1989,8 +1983,8 @@ mysql_execute_command(THD *thd) ...@@ -1989,8 +1983,8 @@ mysql_execute_command(THD *thd)
select privileges for the rest select privileges for the rest
*/ */
{ {
ulong privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ? ulong privilege= (lex->duplicates == DUP_REPLACE ?
INSERT_ACL : INSERT_ACL | DELETE_ACL); INSERT_ACL | DELETE_ACL : INSERT_ACL);
TABLE_LIST *save_next=tables->next; TABLE_LIST *save_next=tables->next;
tables->next=0; tables->next=0;
if (check_access(thd, privilege, if (check_access(thd, privilege,
......
...@@ -204,6 +204,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -204,6 +204,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token DES_KEY_FILE %token DES_KEY_FILE
%token DISABLE_SYM %token DISABLE_SYM
%token DISTINCT %token DISTINCT
%token DUPLICATE
%token DYNAMIC_SYM %token DYNAMIC_SYM
%token ENABLE_SYM %token ENABLE_SYM
%token ENCLOSED %token ENCLOSED
...@@ -642,7 +643,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -642,7 +643,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
repair restore backup analyze check repair restore backup analyze check
field_list field_list_item field_spec kill field_list field_list_item field_spec kill
select_item_list select_item values_list no_braces select_item_list select_item values_list no_braces
limit_clause delete_limit_clause fields opt_values values opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item procedure_list procedure_list2 procedure_item
when_list2 expr_list2 handler when_list2 expr_list2 handler
opt_precision opt_ignore opt_column opt_restrict opt_precision opt_ignore opt_column opt_restrict
...@@ -660,7 +661,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -660,7 +661,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
table_to_table_list table_to_table opt_table_list opt_as table_to_table_list table_to_table opt_table_list opt_as
handler_rkey_function handler_read_or_scan handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild single_multi table_wild_list table_wild_one opt_wild
union union_list union_option union_clause union_list union_option
precision opt_on_delete_item subselect_start opt_and precision opt_on_delete_item subselect_start opt_and
subselect_end select_var_list select_var_list_init help opt_len subselect_end select_var_list select_var_list_init help opt_len
END_OF_INPUT END_OF_INPUT
...@@ -883,7 +884,7 @@ create3: ...@@ -883,7 +884,7 @@ 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_clause {}
; ;
opt_as: opt_as:
...@@ -918,27 +919,23 @@ create_table_options: ...@@ -918,27 +919,23 @@ create_table_options:
| create_table_option create_table_options; | create_table_option create_table_options;
| create_table_option ',' create_table_options; | create_table_option ',' create_table_options;
o_eq:
/* empty */
| EQ {};
create_table_option: create_table_option:
TYPE_SYM o_eq table_types { Lex->create_info.db_type= $3; } TYPE_SYM opt_equal table_types { Lex->create_info.db_type= $3; }
| MAX_ROWS o_eq ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
| MIN_ROWS o_eq ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
| AVG_ROW_LENGTH o_eq ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} | AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
| PASSWORD o_eq TEXT_STRING { Lex->create_info.password=$3.str; } | PASSWORD opt_equal TEXT_STRING { Lex->create_info.password=$3.str; }
| COMMENT_SYM o_eq TEXT_STRING { Lex->create_info.comment=$3.str; } | COMMENT_SYM opt_equal TEXT_STRING { Lex->create_info.comment=$3.str; }
| AUTO_INC o_eq ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
| PACK_KEYS_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| PACK_KEYS_SYM o_eq DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
| CHECKSUM_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; } | CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
| DELAY_KEY_WRITE_SYM o_eq ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; } | DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
| ROW_FORMAT_SYM o_eq row_types { Lex->create_info.row_type= $3; } | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; }
| RAID_TYPE o_eq raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKS o_eq ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| RAID_CHUNKSIZE o_eq ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;} | RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
| UNION_SYM o_eq '(' table_list ')' | UNION_SYM opt_equal '(' table_list ')'
{ {
/* Move the union list to the merge_list */ /* Move the union list to the merge_list */
LEX *lex=Lex; LEX *lex=Lex;
...@@ -951,19 +948,19 @@ create_table_option: ...@@ -951,19 +948,19 @@ create_table_option:
table_list->next=0; table_list->next=0;
lex->create_info.used_fields|= HA_CREATE_USED_UNION; lex->create_info.used_fields|= HA_CREATE_USED_UNION;
} }
| opt_default CHARSET o_eq charset_name_or_default | opt_default CHARSET opt_equal charset_name_or_default
{ {
Lex->create_info.table_charset= $4; Lex->create_info.table_charset= $4;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
} }
| opt_default CHAR_SYM SET o_eq charset_name_or_default | opt_default CHAR_SYM SET opt_equal charset_name_or_default
{ {
Lex->create_info.table_charset= $5; Lex->create_info.table_charset= $5;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET; Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
} }
| INSERT_METHOD o_eq merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
| DATA_SYM DIRECTORY_SYM o_eq TEXT_STRING { Lex->create_info.data_file_name= $4.str; } | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
| INDEX DIRECTORY_SYM o_eq TEXT_STRING { Lex->create_info.index_file_name= $4.str; }; | INDEX DIRECTORY_SYM opt_equal TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
table_types: table_types:
ISAM_SYM { $$= DB_TYPE_ISAM; } ISAM_SYM { $$= DB_TYPE_ISAM; }
...@@ -990,7 +987,7 @@ merge_insert_types: ...@@ -990,7 +987,7 @@ merge_insert_types:
| LAST_SYM { $$= MERGE_INSERT_TO_LAST; }; | LAST_SYM { $$= MERGE_INSERT_TO_LAST; };
opt_select_from: opt_select_from:
/* empty */ opt_limit_clause {}
| select_from select_lock_type; | select_from select_lock_type;
udf_func_type: udf_func_type:
...@@ -1663,7 +1660,7 @@ select_init2: ...@@ -1663,7 +1660,7 @@ select_init2:
YYABORT; YYABORT;
} }
} }
union union_clause
; ;
select_part2: select_part2:
...@@ -1676,16 +1673,18 @@ select_part2: ...@@ -1676,16 +1673,18 @@ select_part2:
select_options select_item_list select_into select_lock_type; select_options select_item_list select_into select_lock_type;
select_into: select_into:
limit_clause {} opt_limit_clause {}
| FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM
clause, and DUAL is system table without fields.
Is "SELECT 1 FROM DUAL" any better than
"SELECT 1" ? Hmmm :) */
| into
| select_from | select_from
| FROM DUAL_SYM | into select_from
| opt_into | select_from into;
| opt_into select_from
| select_from opt_into;
select_from: select_from:
FROM join_table_list where_clause group_clause having_clause opt_order_clause limit_clause procedure_clause; FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause;
select_options: select_options:
/* empty*/ /* empty*/
...@@ -2460,7 +2459,7 @@ join_table: ...@@ -2460,7 +2459,7 @@ join_table:
} }
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
{ add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; } { add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
| '(' SELECT_SYM select_part3 ')' opt_table_alias | '(' SELECT_SYM select_derived ')' opt_table_alias
{ {
LEX *lex=Lex; LEX *lex=Lex;
SELECT_LEX_UNIT *unit= lex->current_select->master_unit(); SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
...@@ -2471,7 +2470,7 @@ join_table: ...@@ -2471,7 +2470,7 @@ join_table:
YYABORT; YYABORT;
}; };
select_part3: select_derived:
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->derived_tables= true; lex->derived_tables= true;
...@@ -2481,11 +2480,8 @@ select_part3: ...@@ -2481,11 +2480,8 @@ select_part3:
mysql_init_select(lex); mysql_init_select(lex);
lex->current_select->linkage= DERIVED_TABLE_TYPE; lex->current_select->linkage= DERIVED_TABLE_TYPE;
} }
select_options select_item_list select_intoto; select_options select_item_list opt_select_from
;
select_intoto:
limit_clause {}
| select_from;
opt_outer: opt_outer:
/* empty */ {} /* empty */ {}
...@@ -2675,7 +2671,7 @@ order_dir: ...@@ -2675,7 +2671,7 @@ order_dir:
| DESC { $$ =0; }; | DESC { $$ =0; };
limit_clause: opt_limit_clause:
/* empty */ {} /* empty */ {}
| LIMIT | LIMIT
{ {
...@@ -2792,7 +2788,7 @@ select_var_ident: '@' ident_or_text ...@@ -2792,7 +2788,7 @@ select_var_ident: '@' ident_or_text
} }
; ;
opt_into: into:
INTO OUTFILE TEXT_STRING INTO OUTFILE TEXT_STRING
{ {
LEX *lex=Lex; LEX *lex=Lex;
...@@ -2904,7 +2900,7 @@ insert: ...@@ -2904,7 +2900,7 @@ insert:
{ {
Select->set_lock_for_tables($3); Select->set_lock_for_tables($3);
} }
insert_field_spec insert_field_spec opt_insert_update
; ;
replace: replace:
...@@ -2977,7 +2973,7 @@ insert_values: ...@@ -2977,7 +2973,7 @@ insert_values:
mysql_init_select(lex); mysql_init_select(lex);
} }
select_options select_item_list select_from select_lock_type select_options select_item_list select_from select_lock_type
union {} union_clause {}
; ;
values_list: values_list:
...@@ -3042,6 +3038,11 @@ expr_or_default: ...@@ -3042,6 +3038,11 @@ expr_or_default:
| DEFAULT {$$= new Item_default(); } | DEFAULT {$$= new Item_default(); }
; ;
opt_insert_update:
/* empty */
| ON DUPLICATE KEY_SYM UPDATE_SYM SET update_list
;
/* Update rows in a table */ /* Update rows in a table */
update: update:
...@@ -3215,7 +3216,7 @@ show_param: ...@@ -3215,7 +3216,7 @@ show_param:
lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
lex->select_lex.select_limit= lex->thd->variables.select_limit; lex->select_lex.select_limit= lex->thd->variables.select_limit;
lex->select_lex.offset_limit= 0L; lex->select_lex.offset_limit= 0L;
} limit_clause } opt_limit_clause
| keys_or_index FROM table_ident opt_db | keys_or_index FROM table_ident opt_db
{ {
Lex->sql_command= SQLCOM_SHOW_KEYS; Lex->sql_command= SQLCOM_SHOW_KEYS;
...@@ -3243,9 +3244,9 @@ show_param: ...@@ -3243,9 +3244,9 @@ show_param:
{ (void) create_select_for_variable("warning_count"); } { (void) create_select_for_variable("warning_count"); }
| COUNT_SYM '(' '*' ')' ERRORS | COUNT_SYM '(' '*' ')' ERRORS
{ (void) create_select_for_variable("error_count"); } { (void) create_select_for_variable("error_count"); }
| WARNINGS {Select->offset_limit=0L;} limit_clause | WARNINGS {Select->offset_limit=0L;} opt_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_WARNS;} { Lex->sql_command = SQLCOM_SHOW_WARNS;}
| ERRORS {Select->offset_limit=0L;} limit_clause | ERRORS {Select->offset_limit=0L;} opt_limit_clause
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;} { Lex->sql_command = SQLCOM_SHOW_ERRORS;}
| STATUS_SYM wild | STATUS_SYM wild
{ Lex->sql_command= SQLCOM_SHOW_STATUS; } { Lex->sql_command= SQLCOM_SHOW_STATUS; }
...@@ -3997,7 +3998,7 @@ handler: ...@@ -3997,7 +3998,7 @@ handler:
if (!lex->current_select->add_table_to_list($2, 0, 0)) if (!lex->current_select->add_table_to_list($2, 0, 0))
YYABORT; YYABORT;
} }
handler_read_or_scan where_clause limit_clause { } handler_read_or_scan where_clause opt_limit_clause { }
; ;
handler_read_or_scan: handler_read_or_scan:
...@@ -4326,7 +4327,7 @@ rollback: ...@@ -4326,7 +4327,7 @@ rollback:
*/ */
union: union_clause:
/* empty */ {} /* empty */ {}
| union_list | union_list
; ;
...@@ -4378,7 +4379,7 @@ optional_order_or_limit: ...@@ -4378,7 +4379,7 @@ optional_order_or_limit:
lex->current_select->select_limit= lex->current_select->select_limit=
lex->thd->variables.select_limit; lex->thd->variables.select_limit;
} }
opt_order_clause limit_clause opt_order_clause opt_limit_clause
; ;
union_option: union_option:
......
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