summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy219
1 files changed, 132 insertions, 87 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 142f52b87ab..9f25e17b6fd 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -32,7 +32,6 @@
#define Select Lex->current_select
#include "mysql_priv.h"
#include "slave.h"
-#include "sql_acl.h"
#include "lex_symbol.h"
#include "item_create.h"
#include <myisam.h>
@@ -131,6 +130,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CLIENT_SYM
%token COMMENT_SYM
%token COMMIT_SYM
+%token CONSISTENT_SYM
%token COUNT_SYM
%token CREATE
%token CROSS
@@ -165,6 +165,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SELECT_SYM
%token SHOW
%token SLAVE
+%token SNAPSHOT_SYM
%token SQL_THREAD
%token START_SYM
%token STD_SYM
@@ -607,7 +608,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <simple_string>
remember_name remember_end opt_ident opt_db text_or_password
- opt_constraint constraint
+ opt_constraint constraint ident_or_empty
%type <string>
text_string opt_gconcat_separator
@@ -618,6 +619,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
table_option opt_if_not_exists opt_no_write_to_binlog opt_var_type
opt_var_ident_type delete_option opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option
+ start_transaction_opts
%type <ulong_num>
ULONG_NUM raid_types merge_insert_types
@@ -1109,7 +1111,7 @@ create_select:
SELECT_SYM
{
LEX *lex=Lex;
- lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
+ lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ;
if (lex->sql_command == SQLCOM_INSERT)
lex->sql_command= SQLCOM_INSERT_SELECT;
else if (lex->sql_command == SQLCOM_REPLACE)
@@ -1358,7 +1360,7 @@ field_spec:
field_ident
{
LEX *lex=Lex;
- lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->length=lex->dec=0; lex->type=0;
lex->default_value= lex->on_update_value= 0;
lex->comment=0;
lex->charset=NULL;
@@ -1371,7 +1373,7 @@ field_spec:
lex->length,lex->dec,lex->type,
lex->default_value, lex->on_update_value,
lex->comment,
- lex->change,lex->interval,lex->charset,
+ lex->change,&lex->interval_list,lex->charset,
lex->uint_geom_type))
YYABORT;
};
@@ -1399,6 +1401,9 @@ type:
| BINARY '(' NUM ')' { Lex->length=$3.str;
Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_STRING; }
+ | BINARY { Lex->length= (char*) "1";
+ Lex->charset=&my_charset_bin;
+ $$=FIELD_TYPE_STRING; }
| varchar '(' NUM ')' opt_binary { Lex->length=$3.str;
$$=FIELD_TYPE_VAR_STRING; }
| nvarchar '(' NUM ')' { Lex->length=$3.str;
@@ -1410,7 +1415,7 @@ type:
| YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; }
| DATE_SYM { $$=FIELD_TYPE_DATE; }
| TIME_SYM { $$=FIELD_TYPE_TIME; }
- | TIMESTAMP
+ | TIMESTAMP opt_len
{
if (YYTHD->variables.sql_mode & MODE_MAXDB)
$$=FIELD_TYPE_DATETIME;
@@ -1423,13 +1428,6 @@ type:
$$=FIELD_TYPE_TIMESTAMP;
}
}
- | TIMESTAMP '(' NUM ')'
- {
- LEX *lex= Lex;
- lex->length= $3.str;
- lex->type|= NOT_NULL_FLAG;
- $$= FIELD_TYPE_TIMESTAMP;
- }
| DATETIME { $$=FIELD_TYPE_DATETIME; }
| TINYBLOB { Lex->charset=&my_charset_bin;
$$=FIELD_TYPE_TINY_BLOB; }
@@ -1465,17 +1463,9 @@ type:
| FIXED_SYM float_options field_options
{ $$=FIELD_TYPE_DECIMAL;}
| ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary
- {
- LEX *lex=Lex;
- lex->interval=typelib(lex->interval_list);
- $$=FIELD_TYPE_ENUM;
- }
+ { $$=FIELD_TYPE_ENUM; }
| SET { Lex->interval_list.empty();} '(' string_list ')' opt_binary
- {
- LEX *lex=Lex;
- lex->interval=typelib(lex->interval_list);
- $$=FIELD_TYPE_SET;
- }
+ { $$=FIELD_TYPE_SET; }
| LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
| SERIAL_SYM
{
@@ -1852,8 +1842,9 @@ alter:
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
- lex->sql_command = SQLCOM_ALTER_TABLE;
- lex->name=0;
+ lex->sql_command= SQLCOM_ALTER_TABLE;
+ lex->name= 0;
+ lex->duplicates= DUP_ERROR;
if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
TL_OPTION_UPDATING))
YYABORT;
@@ -1872,7 +1863,7 @@ alter:
}
alter_list
{}
- | ALTER DATABASE ident
+ | ALTER DATABASE ident_or_empty
{
Lex->create_info.default_table_charset= NULL;
Lex->create_info.used_fields= 0;
@@ -1881,10 +1872,15 @@ alter:
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
- lex->name=$3.str;
+ lex->name= $3;
};
+ident_or_empty:
+ /* empty */ { $$= 0; }
+ | ident { $$= $1.str; };
+
+
alter_list:
| DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; }
| IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; }
@@ -1919,7 +1915,7 @@ alter_list_item:
| MODIFY_SYM opt_column field_ident
{
LEX *lex=Lex;
- lex->length=lex->dec=0; lex->type=0; lex->interval=0;
+ lex->length=lex->dec=0; lex->type=0;
lex->default_value= lex->on_update_value= 0;
lex->comment=0;
lex->charset= NULL;
@@ -1934,7 +1930,7 @@ alter_list_item:
lex->length,lex->dec,lex->type,
lex->default_value, lex->on_update_value,
lex->comment,
- $3.str, lex->interval, lex->charset,
+ $3.str, &lex->interval_list, lex->charset,
lex->uint_geom_type))
YYABORT;
}
@@ -2033,8 +2029,9 @@ opt_column:
| COLUMN_SYM {};
opt_ignore:
- /* empty */ { Lex->duplicates=DUP_ERROR; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
+ /* empty */ { Lex->ignore= 0;}
+ | IGNORE_SYM { Lex->ignore= 1;}
+ ;
opt_restrict:
/* empty */ {}
@@ -2095,10 +2092,21 @@ slave:
start:
- START_SYM TRANSACTION_SYM { Lex->sql_command = SQLCOM_BEGIN;}
- {}
+ START_SYM TRANSACTION_SYM start_transaction_opts
+ {
+ Lex->sql_command = SQLCOM_BEGIN;
+ Lex->start_transaction_opt= $3;
+ }
;
+start_transaction_opts:
+ /*empty*/ { $$ = 0; }
+ | WITH CONSISTENT_SYM SNAPSHOT_SYM
+ {
+ $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
+ }
+ ;
+
slave_thread_opts:
{ Lex->slave_thd_opt= 0; }
slave_thread_opt_list
@@ -2381,7 +2389,10 @@ select:
select_init:
SELECT_SYM select_init2
|
- '(' SELECT_SYM select_part2 ')'
+ '(' select_paren ')' union_opt;
+
+select_paren:
+ SELECT_SYM select_part2
{
LEX *lex= Lex;
SELECT_LEX * sel= lex->current_select;
@@ -2400,7 +2411,8 @@ select_init:
if (sel->master_unit()->fake_select_lex)
sel->master_unit()->global_parameters=
sel->master_unit()->fake_select_lex;
- } union_opt;
+ }
+ | '(' select_paren ')';
select_init2:
select_part2
@@ -2447,10 +2459,11 @@ select_into:
select_from:
FROM join_table_list where_clause group_clause having_clause
opt_order_clause opt_limit_clause procedure_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 :) */
+ | FROM DUAL_SYM opt_limit_clause
+ /* 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 :) */
;
select_options:
@@ -2889,7 +2902,7 @@ simple_expr:
| CONCAT '(' expr_list ')'
{ $$= new Item_func_concat(* $3); }
| CONCAT_WS '(' expr ',' expr_list ')'
- { $$= new Item_func_concat_ws($3, *$5); }
+ { $5->push_front($3); $$= new Item_func_concat_ws(*$5); }
| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
{
Lex->time_zone_tables_used= &fake_time_zone_tables_list;
@@ -3297,7 +3310,7 @@ opt_distinct:
|DISTINCT { $$ = 1; };
opt_gconcat_separator:
- /* empty */ { $$ = new (&YYTHD->mem_root) String(",",1,default_charset_info); }
+ /* empty */ { $$ = new (YYTHD->mem_root) String(",",1,default_charset_info); }
|SEPARATOR_SYM text_string { $$ = $2; };
@@ -3395,8 +3408,7 @@ when_list2:
};
join_table_list:
- '(' join_table_list ')' { $$=$2; }
- | join_table { $$=$1; }
+ join_table { $$=$1; }
| join_table_list ',' join_table_list { $$=$3; }
| join_table_list normal_join join_table_list { $$=$3; }
| join_table_list STRAIGHT_JOIN join_table_list
@@ -3473,7 +3485,7 @@ join_table:
}
| '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}'
{ add_join_on($7,$9); $7->outer_join|=JOIN_TYPE_LEFT; $$=$7; }
- | '(' SELECT_SYM select_derived ')' opt_table_alias
+ | '(' select_derived union_opt ')' opt_table_alias
{
LEX *lex=Lex;
SELECT_LEX_UNIT *unit= lex->current_select->master_unit();
@@ -3484,9 +3496,27 @@ join_table:
(List<String> *)0)))
YYABORT;
- };
+ }
+ | '(' join_table_list ')' { $$=$2; };
select_derived:
+ SELECT_SYM select_derived2
+ | '(' select_derived ')'
+ {
+ LEX *lex= Lex;
+ SELECT_LEX * sel= lex->current_select;
+ if (sel->set_braces(1))
+ {
+ yyerror(ER(ER_SYNTAX_ERROR));
+ YYABORT;
+ }
+ /* select in braces, can't contain global parameters */
+ if (sel->master_unit()->fake_select_lex)
+ sel->master_unit()->global_parameters=
+ sel->master_unit()->fake_select_lex;
+ };
+
+select_derived2:
{
LEX *lex= Lex;
lex->derived_tables= 1;
@@ -3508,7 +3538,7 @@ select_derived:
{
Select->parsing_place= NO_MATTER;
}
- opt_select_from union_opt
+ opt_select_from
;
opt_outer:
@@ -3551,15 +3581,15 @@ key_list_or_empty:
key_usage_list2:
key_usage_list2 ',' ident
{ Select->
- interval_list.push_back(new (&YYTHD->mem_root) String((const char*) $3.str, $3.length,
+ interval_list.push_back(new (YYTHD->mem_root) String((const char*) $3.str, $3.length,
system_charset_info)); }
| ident
{ Select->
- interval_list.push_back(new (&YYTHD->mem_root) String((const char*) $1.str, $1.length,
+ interval_list.push_back(new (YYTHD->mem_root) String((const char*) $1.str, $1.length,
system_charset_info)); }
| PRIMARY_SYM
{ Select->
- interval_list.push_back(new (&YYTHD->mem_root) String("PRIMARY", 7,
+ interval_list.push_back(new (YYTHD->mem_root) String("PRIMARY", 7,
system_charset_info)); };
using_list:
@@ -3915,11 +3945,12 @@ do: DO_SYM
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_DO;
- if (!(lex->insert_list = new List_item))
- YYABORT;
+ mysql_init_select(lex);
+ }
+ expr_list
+ {
+ Lex->insert_list= $3;
}
- values
- {}
;
/*
@@ -3998,7 +4029,9 @@ insert:
INSERT
{
LEX *lex= Lex;
- lex->sql_command = SQLCOM_INSERT;
+ lex->sql_command= SQLCOM_INSERT;
+ lex->duplicates= DUP_ERROR;
+ mysql_init_select(lex);
/* for subselects */
lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ;
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
@@ -4018,6 +4051,7 @@ replace:
LEX *lex=Lex;
lex->sql_command = SQLCOM_REPLACE;
lex->duplicates= DUP_REPLACE;
+ mysql_init_select(lex);
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
}
replace_lock_option insert2
@@ -4147,21 +4181,8 @@ expr_or_default:
opt_insert_update:
/* empty */
- | ON DUPLICATE_SYM
- {
- LEX *lex= Lex;
- /*
- For simplicity, let's forget about INSERT ... SELECT ... UPDATE
- for a moment.
- */
- if (lex->sql_command != SQLCOM_INSERT)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->duplicates= DUP_UPDATE;
- }
- KEY_SYM UPDATE_SYM update_list
+ | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
+ KEY_SYM UPDATE_SYM insert_update_list
;
/* Update rows in a table */
@@ -4173,6 +4194,7 @@ update:
mysql_init_select(lex);
lex->sql_command= SQLCOM_UPDATE;
lex->lock_option= TL_UNLOCK; /* Will be set later */
+ lex->duplicates= DUP_ERROR;
}
opt_low_priority opt_ignore join_table_list
SET update_list
@@ -4197,16 +4219,28 @@ update:
;
update_list:
- update_list ',' simple_ident equal expr_or_default
+ update_list ',' update_elem
+ | update_elem;
+
+update_elem:
+ simple_ident equal expr_or_default
{
- if (add_item_to_list(YYTHD, $3) || add_value_to_list(YYTHD, $5))
+ if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
YYABORT;
- }
- | simple_ident equal expr_or_default
- {
- if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
- YYABORT;
- };
+ };
+
+insert_update_list:
+ insert_update_list ',' insert_update_elem
+ | insert_update_elem;
+
+insert_update_elem:
+ simple_ident equal expr_or_default
+ {
+ LEX *lex= Lex;
+ if (lex->update_list.push_back($1) ||
+ lex->value_list.push_back($3))
+ YYABORT;
+ };
opt_low_priority:
/* empty */ { $$= YYTHD->update_lock_default; }
@@ -4219,7 +4253,9 @@ delete:
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_DELETE;
+ mysql_init_select(lex);
lex->lock_option= lex->thd->update_lock_default;
+ lex->ignore= 0;
lex->select_lex.init_order();
}
opt_delete_options single_multi {}
@@ -4276,7 +4312,7 @@ opt_delete_options:
opt_delete_option:
QUICK { Select->options|= OPTION_QUICK; }
| LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }
- | IGNORE_SYM { Lex->duplicates= DUP_IGNORE; };
+ | IGNORE_SYM { Lex->ignore= 1; };
truncate:
TRUNCATE_SYM opt_table_sym table_name
@@ -4507,7 +4543,7 @@ opt_db:
wild:
/* empty */
| LIKE TEXT_STRING_sys
- { Lex->wild= new (&YYTHD->mem_root) String($2.str, $2.length,
+ { Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
system_charset_info); };
opt_full:
@@ -4561,7 +4597,7 @@ opt_describe_column:
/* empty */ {}
| text_string { Lex->wild= $1; }
| ident
- { Lex->wild= new (&YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); };
+ { Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); };
/* flush things */
@@ -4685,6 +4721,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys
lex->sql_command= SQLCOM_LOAD;
lex->lock_option= $3;
lex->local_file= $4;
+ lex->duplicates= DUP_ERROR;
+ lex->ignore= 0;
if (!(lex->exchange= new sql_exchange($6.str,0)))
YYABORT;
lex->field_list.empty();
@@ -4722,7 +4760,7 @@ load_data_lock:
opt_duplicate:
/* empty */ { Lex->duplicates=DUP_ERROR; }
| REPLACE { Lex->duplicates=DUP_REPLACE; }
- | IGNORE_SYM { Lex->duplicates=DUP_IGNORE; };
+ | IGNORE_SYM { Lex->ignore= 1; };
opt_field_term:
/* empty */
@@ -4802,7 +4840,7 @@ text_literal:
text_string:
TEXT_STRING_literal
- { $$= new (&YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); }
+ { $$= new (YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); }
| HEX_NUM
{
Item *tmp = new Item_varbinary($1.str,$1.length);
@@ -5122,6 +5160,7 @@ keyword:
| COMMIT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
+ | CONSISTENT_SYM {}
| CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
@@ -5262,6 +5301,7 @@ keyword:
| SHARE_SYM {}
| SHUTDOWN {}
| SLAVE {}
+ | SNAPSHOT_SYM {}
| SOUNDS_SYM {}
| SQL_CACHE_SYM {}
| SQL_BUFFER_RESULT {}
@@ -5306,6 +5346,7 @@ set:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_SET_OPTION;
+ mysql_init_select(lex);
lex->option_type=OPT_SESSION;
lex->var_list.empty();
lex->one_shot_set= 0;
@@ -5612,7 +5653,7 @@ revoke_command:
grant_privileges ON opt_table FROM user_list
{}
|
- ALL PRIVILEGES ',' GRANT OPTION FROM user_list
+ ALL opt_privileges ',' GRANT OPTION FROM user_list
{
Lex->sql_command = SQLCOM_REVOKE_ALL;
}
@@ -5638,10 +5679,14 @@ grant:
grant_privileges:
grant_privilege_list {}
- | ALL PRIVILEGES { Lex->grant = GLOBAL_ACLS;}
- | ALL { Lex->grant = GLOBAL_ACLS;}
+ | ALL opt_privileges { Lex->grant = GLOBAL_ACLS;}
;
+opt_privileges:
+ /* empty */
+ | PRIVILEGES
+ ;
+
grant_privilege_list:
grant_privilege
| grant_privilege_list ',' grant_privilege;
@@ -5821,7 +5866,7 @@ column_list:
column_list_id:
ident
{
- String *new_str = new (&YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
+ String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
List_iterator <LEX_COLUMN> iter(Lex->columns);
class LEX_COLUMN *point;
LEX *lex=Lex;
@@ -5888,7 +5933,7 @@ grant_option:
;
begin:
- BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN;} opt_work {}
+ BEGIN_SYM { Lex->sql_command = SQLCOM_BEGIN; Lex->start_transaction_opt= 0;} opt_work {}
;
opt_work: