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.yy220
1 files changed, 163 insertions, 57 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 55f165c0739..318d563b88a 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2001 MySQL AB
+/* Copyright (C) 2000-2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -222,6 +222,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FIRST_SYM
%token FIXED_SYM
%token FLOAT_NUM
+%token FORCE_SYM
%token FOREIGN
%token FROM
%token FULL
@@ -587,7 +588,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
table_wild opt_pad no_in_expr expr_expr simple_expr no_and_expr
using_list expr_or_default set_expr_or_default
- param_marker singleval_subselect singleval_subselect_init
+ param_marker singlerow_subselect singlerow_subselect_init
exists_subselect exists_subselect_init
%type <item_list>
@@ -633,7 +634,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <charset>
charset_name
charset_name_or_default
- opt_db_default_character_set
+ collation_name
+ collation_name_or_default
%type <variable> internal_variable_name
@@ -822,7 +824,8 @@ create:
($2 &
HA_LEX_CREATE_TMP_TABLE ?
&tmp_table_alias :
- (LEX_STRING*) 0),1,
+ (LEX_STRING*) 0),
+ TL_OPTION_UPDATING,
((using_update_log)?
TL_READ_NO_INSERT:
TL_READ)))
@@ -835,6 +838,7 @@ create:
lex->create_info.options=$2 | $4;
lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type;
lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info;
+ lex->name=0;
}
create2
{}
@@ -842,7 +846,8 @@ create:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!lex->current_select->add_table_to_list(lex->thd, $7,NULL,1))
+ if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
@@ -856,13 +861,14 @@ create:
lex->key_list.push_back(new Key($2,$4.str, $5, lex->col_list));
lex->col_list.empty();
}
- | CREATE DATABASE opt_if_not_exists ident opt_db_default_character_set
+ | CREATE DATABASE opt_if_not_exists ident
+ { Lex->create_info.table_charset=NULL; }
+ opt_create_database_options
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_CREATE_DB;
lex->name=$4.str;
lex->create_info.options=$3;
- lex->create_info.table_charset=$5;
}
| CREATE udf_func_type UDF_SYM ident
{
@@ -883,7 +889,13 @@ create:
create2:
'(' field_list ')' opt_create_table_options create3 {}
| opt_create_table_options create3 {}
- ;
+ | LIKE table_ident
+ {
+ LEX *lex=Lex;
+ if (!(lex->name= (char *)$2))
+ YYABORT;
+ }
+ ;
create3:
/* empty */ {}
@@ -900,6 +912,22 @@ opt_as:
/* empty */ {}
| AS {};
+opt_create_database_options:
+ /* empty */ {}
+ | create_database_options {};
+
+create_database_options:
+ create_database_option {}
+ | create_database_options create_database_option {};
+
+create_database_option:
+ COLLATE_SYM collation_name_or_default
+ { Lex->create_info.table_charset=$2; }
+ | opt_default CHAR_SYM SET charset_name_or_default
+ { Lex->create_info.table_charset=$4; }
+ | opt_default CHARSET charset_name_or_default
+ { Lex->create_info.table_charset=$3; };
+
opt_table_options:
/* empty */ { $$= 0; }
| table_options { $$= $1;};
@@ -967,6 +995,11 @@ create_table_option:
Lex->create_info.table_charset= $5;
Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
}
+ | COLLATE_SYM opt_equal collation_name_or_default
+ {
+ Lex->create_info.table_charset= $3;
+ Lex->create_info.used_fields|= HA_CREATE_USED_CHARSET;
+ }
| 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 opt_equal TEXT_STRING { Lex->create_info.data_file_name= $4.str; }
| INDEX DIRECTORY_SYM opt_equal TEXT_STRING { Lex->create_info.index_file_name= $4.str; };
@@ -997,6 +1030,7 @@ merge_insert_types:
opt_select_from:
opt_limit_clause {}
+ | FROM DUAL_SYM {}
| select_from select_lock_type;
udf_func_type:
@@ -1223,19 +1257,26 @@ attribute:
| opt_primary KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
- | COMMENT_SYM text_literal { Lex->comment= $2; };
+ | COMMENT_SYM text_literal { Lex->comment= $2; }
+ | COLLATE_SYM collation_name { Lex->charset=$2; };
charset_name:
- BINARY
+ ident
{
- if (!($$=get_charset_by_name("binary",MYF(0))))
+ if (!($$=get_charset_by_csname($1.str,MYF(0))))
{
- net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,"binary");
+ net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str);
YYABORT;
}
- }
- | ident
+ };
+
+charset_name_or_default:
+ charset_name { $$=$1; }
+ | DEFAULT { $$=NULL; } ;
+
+collation_name:
+ ident
{
if (!($$=get_charset_by_name($1.str,MYF(0))))
{
@@ -1244,19 +1285,14 @@ charset_name:
}
};
-charset_name_or_default:
- charset_name { $$=$1; }
+collation_name_or_default:
+ collation_name { $$=$1; }
| DEFAULT { $$=NULL; } ;
opt_default:
/* empty */ {}
| DEFAULT {};
-opt_db_default_character_set:
- /* empty */ { $$=default_charset_info; }
- | opt_default CHAR_SYM SET charset_name_or_default { $$=$4; }
- | opt_default CHARSET charset_name_or_default { $$=$3; };
-
opt_binary:
/* empty */ { Lex->charset=NULL; }
| ASCII_SYM { Lex->charset=my_charset_latin1; }
@@ -1270,7 +1306,6 @@ opt_binary:
YYABORT;
}
}
- | COLLATE_SYM charset_name { Lex->charset=$2; }
| CHAR_SYM SET charset_name { Lex->charset=$3; } ;
opt_primary:
@@ -1347,7 +1382,8 @@ opt_unique_or_fulltext:
key_alg:
/* empty */ { $$= HA_KEY_ALG_UNDEF; }
- | USING opt_btree_or_rtree { $$= $2; };
+ | USING opt_btree_or_rtree { $$= $2; }
+ | TYPE_SYM opt_btree_or_rtree { $$= $2; };
opt_btree_or_rtree:
BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
@@ -1381,7 +1417,8 @@ alter:
LEX *lex=&thd->lex;
lex->sql_command = SQLCOM_ALTER_TABLE;
lex->name=0;
- if (!lex->select_lex.add_table_to_list(thd, $4, NULL,1))
+ if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
lex->drop_primary=0;
lex->create_list.empty();
@@ -1400,12 +1437,11 @@ alter:
}
alter_list
{}
- | ALTER DATABASE ident opt_db_default_character_set
+ | ALTER DATABASE ident opt_create_database_options
{
LEX *lex=Lex;
lex->sql_command=SQLCOM_ALTER_DB;
lex->name=$3.str;
- lex->create_info.table_charset=$4;
};
@@ -1648,8 +1684,10 @@ table_to_table:
{
LEX *lex=Lex;
SELECT_LEX_NODE *sl= lex->current_select;
- if (!sl->add_table_to_list(lex->thd, $1,NULL,1,TL_IGNORE) ||
- !sl->add_table_to_list(lex->thd, $3,NULL,1,TL_IGNORE))
+ if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
+ TL_IGNORE) ||
+ !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
+ TL_IGNORE))
YYABORT;
};
@@ -1668,12 +1706,17 @@ select_init:
'(' SELECT_SYM select_part2 ')'
{
LEX *lex= Lex;
- SELECT_LEX_NODE * sel= lex->current_select;
+ SELECT_LEX * sel= lex->current_select->select_lex();
if (sel->set_braces(1))
{
send_error(lex->thd, ER_SYNTAX_ERROR);
YYABORT;
}
+ if (sel->linkage == UNION_TYPE && !sel->master_unit()->first_select()->braces)
+ {
+ send_error(lex->thd, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
/* select in braces, can't contain global parameters */
sel->master_unit()->global_parameters=
sel->master_unit();
@@ -1683,11 +1726,17 @@ select_init2:
select_part2
{
LEX *lex= Lex;
+ SELECT_LEX * sel= lex->current_select->select_lex();
if (lex->current_select->set_braces(0))
{
send_error(lex->thd, ER_SYNTAX_ERROR);
YYABORT;
}
+ if (sel->linkage == UNION_TYPE && sel->master_unit()->first_select()->braces)
+ {
+ send_error(lex->thd, ER_SYNTAX_ERROR);
+ YYABORT;
+ }
}
union_clause
;
@@ -1695,6 +1744,7 @@ select_init2:
select_part2:
{
LEX *lex=Lex;
+ SELECT_LEX * sel= lex->current_select->select_lex();
if (lex->current_select == &lex->select_lex)
lex->lock_option= TL_READ; /* Only for global SELECT */
mysql_init_select(lex);
@@ -1880,7 +1930,7 @@ expr_expr:
{ $$= new Item_date_add_interval($1,$4,$5,0); }
| expr '-' INTERVAL_SYM expr interval
{ $$= new Item_date_add_interval($1,$4,$5,1); }
- | expr COLLATE_SYM charset_name
+ | expr COLLATE_SYM collation_name
{ $$= new Item_func_set_collation($1,$3); };
/* expressions that begin with 'expr' that do NOT follow IN_SYM */
@@ -2017,7 +2067,7 @@ simple_expr:
$$= new Item_row(*$5);
}
| EXISTS exists_subselect { $$= $2; }
- | singleval_subselect { $$= $1; }
+ | singlerow_subselect { $$= $1; }
| '{' ident expr '}' { $$= $3; }
| MATCH ident_list_arg AGAINST '(' expr ')'
{ Select->add_ftfunc_to_list((Item_func_match *)
@@ -2201,9 +2251,9 @@ simple_expr:
| NOW_SYM '(' expr ')'
{ $$= new Item_func_now($3); Lex->safe_to_cache_query=0;}
| PASSWORD '(' expr ')'
- {
- $$= new Item_func_password($3);
- }
+ { $$= new Item_func_password($3); }
+ | PASSWORD '(' expr ',' expr ')'
+ { $$= new Item_func_password($3,$5); }
| POINTFROMTEXT '(' expr ')'
{ $$= new Item_func_geometry_from_text($3); }
| POINTFROMTEXT '(' expr ',' expr ')'
@@ -2489,12 +2539,14 @@ join_table:
{
SELECT_LEX *sel= Select->select_lex();
sel->use_index_ptr=sel->ignore_index_ptr=0;
+ sel->table_join_options= 0;
}
table_ident opt_table_alias opt_key_definition
{
LEX *lex= Lex;
SELECT_LEX_NODE *sel= lex->current_select;
- if (!($$= sel->add_table_to_list(lex->thd, $2, $3, 0,
+ if (!($$= sel->add_table_to_list(lex->thd, $2, $3,
+ sel->get_table_join_options(),
lex->lock_option,
sel->get_use_index(),
sel->get_ignore_index())))
@@ -2509,7 +2561,9 @@ join_table:
lex->current_select= unit->outer_select();
if (!($$= lex->current_select->
add_table_to_list(lex->thd, new Table_ident(unit), $5, 0,
- lex->lock_option)))
+ TL_READ,(List<String> *)0,
+ (List<String> *)0)))
+
YYABORT;
};
@@ -2538,6 +2592,13 @@ opt_key_definition:
sel->use_index= *$2;
sel->use_index_ptr= &sel->use_index;
}
+ | FORCE_SYM key_usage_list
+ {
+ SELECT_LEX *sel= Select->select_lex();
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ sel->table_join_options|= TL_OPTION_FORCE_INDEX;
+ }
| IGNORE_SYM key_usage_list
{
SELECT_LEX *sel= Select->select_lex();
@@ -2547,8 +2608,14 @@ opt_key_definition:
key_usage_list:
key_or_index { Select->select_lex()->interval_list.empty(); }
- '(' key_usage_list2 ')'
- { $$= &Select->select_lex()->interval_list; };
+ '(' key_list_or_empty ')'
+ { $$= &Select->select_lex()->interval_list; }
+ ;
+
+key_list_or_empty:
+ /* empty */ {}
+ | key_usage_list2 {}
+ ;
key_usage_list2:
key_usage_list2 ',' ident
@@ -2909,7 +2976,8 @@ drop:
lex->drop_list.empty();
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
- if (!lex->current_select->add_table_to_list(lex->thd, $5,NULL, 1))
+ if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
+ TL_OPTION_UPDATING))
YYABORT;
}
| DROP DATABASE if_exists ident
@@ -2933,7 +3001,11 @@ table_list:
table_name:
table_ident
- { if (!Select->add_table_to_list(YYTHD, $1, NULL, 1)) YYABORT; };
+ {
+ if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING))
+ YYABORT;
+ }
+ ;
if_exists:
/* empty */ { $$= 0; }
@@ -3168,7 +3240,8 @@ delete:
single_multi:
FROM table_ident
{
- if (!Select->add_table_to_list(YYTHD, $2, NULL, 1, Lex->lock_option))
+ if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
+ Lex->lock_option))
YYABORT;
}
where_clause opt_order_clause
@@ -3187,16 +3260,17 @@ table_wild_list:
| table_wild_list ',' table_wild_one {};
table_wild_one:
- ident opt_wild
+ ident opt_wild opt_table_alias
{
- if (!Select->add_table_to_list(YYTHD, new Table_ident($1), NULL, 1,
- Lex->lock_option))
+ if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
+ TL_OPTION_UPDATING, Lex->lock_option))
YYABORT;
}
- | ident '.' ident opt_wild
+ | ident '.' ident opt_wild opt_table_alias
{
if (!Select->add_table_to_list(YYTHD, new Table_ident($1, $3, 0),
- NULL, 1, Lex->lock_option))
+ $5, TL_OPTION_UPDATING,
+ Lex->lock_option))
YYABORT;
}
;
@@ -3360,7 +3434,7 @@ show_param:
| CREATE TABLE_SYM table_ident
{
Lex->sql_command = SQLCOM_SHOW_CREATE;
- if(!Select->add_table_to_list(YYTHD, $3, NULL,0))
+ if (!Select->add_table_to_list(YYTHD, $3, NULL,0))
YYABORT;
}
| MASTER_SYM STATUS_SYM
@@ -3529,14 +3603,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_spec
{
- if (!Select->add_table_to_list(YYTHD, $11, NULL, 1))
+ if (!Select->add_table_to_list(YYTHD, $11, NULL, TL_OPTION_UPDATING))
YYABORT;
}
|
LOAD TABLE_SYM table_ident FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
- if (!Select->add_table_to_list(YYTHD, $3, NULL, 1))
+ if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING))
YYABORT;
}
@@ -3666,17 +3740,41 @@ simple_ident:
}
| ident '.' ident
{
- SELECT_LEX_NODE *sel=Select;
+ THD *thd= YYTHD;
+ LEX *lex= &thd->lex;
+ SELECT_LEX_NODE *sel= lex->current_select;
+ if (sel->no_table_names_allowed)
+ {
+ my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
+ ER(ER_TABLENAME_NOT_ALLOWED_HERE),
+ MYF(0), $1.str, thd->where);
+ }
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str);
}
| '.' ident '.' ident
{
- SELECT_LEX_NODE *sel=Select;
+ THD *thd= YYTHD;
+ LEX *lex= &thd->lex;
+ SELECT_LEX_NODE *sel= lex->current_select;
+ if (sel->no_table_names_allowed)
+ {
+ my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
+ ER(ER_TABLENAME_NOT_ALLOWED_HERE),
+ MYF(0), $2.str, thd->where);
+ }
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str);
}
| ident '.' ident '.' ident
{
- SELECT_LEX_NODE *sel=Select;
+ THD *thd= YYTHD;
+ LEX *lex= &thd->lex;
+ SELECT_LEX_NODE *sel= lex->current_select;
+ if (sel->no_table_names_allowed)
+ {
+ my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
+ ER(ER_TABLENAME_NOT_ALLOWED_HERE),
+ MYF(0), $3.str, thd->where);
+ }
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str);
};
@@ -4461,7 +4559,8 @@ optional_order_or_limit:
/* Empty */ {}
|
{
- LEX *lex=Lex;
+ THD *thd= YYTHD;
+ LEX *lex= &thd->lex;
if (!lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
{
send_error(lex->thd, ER_SYNTAX_ERROR);
@@ -4473,8 +4572,15 @@ optional_order_or_limit:
lex->current_select= sel->master_unit();
lex->current_select->select_limit=
lex->thd->variables.select_limit;
+ lex->current_select->no_table_names_allowed= 1;
+ thd->where= "global ORDER clause";
}
order_or_limit
+ {
+ THD *thd= YYTHD;
+ thd->lex.current_select->no_table_names_allowed= 0;
+ thd->where= "";
+ }
;
order_or_limit:
@@ -4487,17 +4593,17 @@ union_option:
/* empty */ {}
| ALL {Select->master_unit()->union_option= 1;};
-singleval_subselect:
- subselect_start singleval_subselect_init
+singlerow_subselect:
+ subselect_start singlerow_subselect_init
subselect_end
{
$$= $2;
};
-singleval_subselect_init:
+singlerow_subselect_init:
select_init2
{
- $$= new Item_singleval_subselect(YYTHD,
+ $$= new Item_singlerow_subselect(YYTHD,
Lex->current_select->master_unit()->
first_select());
};