diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 416 |
1 files changed, 267 insertions, 149 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e2e17d98f2c..af5d6690133 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -69,6 +69,7 @@ inline Item *or_or_concat(Item* A, Item* B) enum Item_cast cast_type; enum Item_udftype udf_type; CHARSET_INFO *charset; + thr_lock_type lock_type; interval_type interval; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; @@ -88,6 +89,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token NEXT_SYM %token PREV_SYM +%token DIV_SYM %token EQ %token EQUAL_SYM %token GE @@ -96,6 +98,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token LT %token NE %token IS +%token MOD_SYM %token SHIFT_LEFT %token SHIFT_RIGHT %token SET_VAR @@ -118,6 +121,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CROSS %token CUBE_SYM %token DELETE_SYM +%token DUAL_SYM %token DO_SYM %token DROP %token EVENTS_SYM @@ -170,13 +174,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token BOTH %token BTREE_SYM %token BY +%token BYTE_SYM %token CACHE_SYM %token CASCADE %token CAST_SYM %token CHARSET %token CHECKSUM_SYM %token CHECK_SYM -%token CIPHER %token COMMITTED_SYM %token COLLATE_SYM %token COLUMNS @@ -202,6 +206,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ESCAPE_SYM %token EXISTS %token EXTENDED_SYM +%token FALSE_SYM %token FILE_SYM %token FIRST_SYM %token FIXED_SYM @@ -232,7 +237,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token IN_SYM %token ISOLATION %token ISAM_SYM -%token ISSUER %token JOIN_SYM %token KEYS %token KEY_SYM @@ -252,7 +256,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MASTER_USER_SYM %token MASTER_LOG_FILE_SYM %token MASTER_LOG_POS_SYM -%token MASTER_LOG_SEQ_SYM %token MASTER_PASSWORD_SYM %token MASTER_PORT_SYM %token MASTER_CONNECT_RETRY_SYM @@ -273,10 +276,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token NEW_SYM %token NCHAR_SYM %token NOT -%token NO_FOREIGN_KEY_CHECKS %token NO_SYM %token NULL_SYM %token NUM +%token OFFSET_SYM %token ON %token OPEN_SYM %token OPTION @@ -303,7 +306,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token REAL_NUM %token REFERENCES %token REGEXP -%token RELAXED_UNIQUE_CHECKS %token RELOAD %token RENAME %token REPEATABLE_SYM @@ -317,6 +319,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token ROW_SYM %token RTREE_SYM %token SET +%token SERIAL_SYM %token SERIALIZABLE_SYM %token SESSION_SYM %token SIMPLE_SYM @@ -335,6 +338,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token TO_SYM %token TRAILING %token TRANSACTION_SYM +%token TRUE_SYM %token TYPE_SYM %token TYPES_SYM %token FUNC_ARG0 @@ -352,6 +356,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token USE_FRM %token USE_SYM %token USING +%token VALUE_SYM %token VALUES %token VARIABLES %token WHERE @@ -519,7 +524,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %left '&' %left SHIFT_LEFT SHIFT_RIGHT %left '-' '+' -%left '*' '/' '%' +%left '*' '/' '%' DIV_SYM MOD_SYM %left NEG '~' %left XOR %left '^' @@ -543,7 +548,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_ident references %type <simple_string> - remember_name remember_end opt_len opt_ident opt_db text_or_password + remember_name remember_end opt_ident opt_db text_or_password opt_escape %type <string> @@ -553,7 +558,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); type int_type real_type order_dir opt_field_spec lock_option udf_type if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_var_type opt_var_ident_type - delete_option all_or_any + delete_option opt_temporary all_or_any %type <ulong_num> ULONG_NUM raid_types merge_insert_types @@ -561,6 +566,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <ulonglong_number> ulonglong_num +%type <lock_type> + replace_lock_option opt_low_priority insert_lock_option load_data_lock + %type <item> literal text_literal insert_ident order_ident simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr @@ -636,23 +644,25 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); field_opt_list opt_binary table_lock_list table_lock varchar ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use opt_delete_options opt_delete_option - opt_outer table_list table_name opt_option opt_place opt_low_priority + opt_outer table_list table_name opt_option opt_place opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges opt_table user_list grant_option grant_privilege grant_privilege_list - flush_options flush_option insert_lock_option replace_lock_option + flush_options flush_option equal optional_braces opt_key_definition key_usage_list2 opt_mi_check_type opt_to mi_check_types normal_join table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan - single_multi table_wild_list table_wild_one opt_wild union - precision union_option opt_on_delete_item subselect_start opt_and - subselect_end select_var_list select_var_list_init help + single_multi table_wild_list table_wild_one opt_wild + union union_option + precision opt_on_delete_item subselect_start opt_and + subselect_end select_var_list select_var_list_init help opt_len END_OF_INPUT %type <NONE> '-' '+' '*' '/' '%' '(' ')' - ',' '!' '{' '}' '&' '|' AND OR OR_OR_CONCAT BETWEEN_SYM CASE_SYM THEN_SYM WHEN_SYM + ',' '!' '{' '}' '&' '|' AND OR OR_OR_CONCAT BETWEEN_SYM CASE_SYM + THEN_SYM WHEN_SYM DIV_SYM MOD_SYM %% @@ -729,7 +739,7 @@ change: { LEX *lex = Lex; lex->sql_command = SQLCOM_CHANGE_MASTER; - memset(&lex->mi, 0, sizeof(lex->mi)); + bzero((char*) &lex->mi, sizeof(lex->mi)); } master_defs; master_defs: @@ -796,7 +806,10 @@ create: ($2 & HA_LEX_CREATE_TMP_TABLE ? &tmp_table_alias : - (LEX_STRING*) 0),1)) + (LEX_STRING*) 0),1, + ((using_update_log)? + TL_READ_NO_INSERT: + TL_READ))) YYABORT; lex->create_list.empty(); lex->key_list.empty(); @@ -989,7 +1002,7 @@ field_list: field_list_item: - field_spec + field_spec check_constraint | field_spec references { Lex->col_list.empty(); /* Alloced by sql_alloc */ @@ -1011,10 +1024,16 @@ field_list_item: lex->fk_match_option)); lex->col_list.empty(); /* Alloced by sql_alloc */ } - | opt_constraint CHECK_SYM '(' expr ')' + | opt_constraint check_constraint { Lex->col_list.empty(); /* Alloced by sql_alloc */ - }; + } + ; + +check_constraint: + /* empty */ + | CHECK_SYM expr + ; opt_constraint: /* empty */ @@ -1040,7 +1059,7 @@ field_spec: }; type: - int_type opt_len field_options { Lex->length=$2; $$=$1; } + int_type opt_len field_options { $$=$1; } | real_type opt_precision field_options { $$=$1; } | FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; } | BIT_SYM opt_len { Lex->length=(char*) "1"; @@ -1059,16 +1078,22 @@ type: | VARBINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=my_charset_bin; $$=FIELD_TYPE_VAR_STRING; } - | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; Lex->length=$2; } + | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } | DATE_SYM { $$=FIELD_TYPE_DATE; } | TIME_SYM { $$=FIELD_TYPE_TIME; } - | TIMESTAMP { $$=FIELD_TYPE_TIMESTAMP; } + | TIMESTAMP + { + if (current_thd->sql_mode & MODE_SAPDB) + $$=FIELD_TYPE_DATETIME; + else + $$=FIELD_TYPE_TIMESTAMP; + } | TIMESTAMP '(' NUM ')' { Lex->length=$3.str; $$=FIELD_TYPE_TIMESTAMP; } | DATETIME { $$=FIELD_TYPE_DATETIME; } | TINYBLOB { Lex->charset=my_charset_bin; $$=FIELD_TYPE_TINY_BLOB; } - | BLOB_SYM { Lex->charset=my_charset_bin; + | BLOB_SYM opt_len { Lex->charset=my_charset_bin; $$=FIELD_TYPE_BLOB; } | GEOMETRY_SYM { Lex->charset=my_charset_bin; $$=FIELD_TYPE_GEOMETRY; } @@ -1080,13 +1105,15 @@ type: $$=FIELD_TYPE_MEDIUM_BLOB; } | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; } - | TEXT_SYM opt_binary { $$=FIELD_TYPE_BLOB; } + | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; } | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; } | DECIMAL_SYM float_options field_options { $$=FIELD_TYPE_DECIMAL;} | NUMERIC_SYM float_options field_options { $$=FIELD_TYPE_DECIMAL;} + | FIXED_SYM float_options field_options + { $$=FIELD_TYPE_DECIMAL;} | ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary { LEX *lex=Lex; @@ -1098,7 +1125,15 @@ type: LEX *lex=Lex; lex->interval=typelib(lex->interval_list); $$=FIELD_TYPE_SET; - }; + } + | LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | SERIAL_SYM + { + $$=FIELD_TYPE_LONGLONG; + Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | + UNIQUE_FLAG); + } + ; char: CHAR_SYM {} @@ -1151,8 +1186,8 @@ field_option: | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; opt_len: - /* empty */ { $$=(char*) 0; } /* use default length */ - | '(' NUM ')' { $$=$2.str; }; + /* empty */ { Lex->length=(char*) 0; } /* use default length */ + | '(' NUM ')' { Lex->length= $2.str; }; opt_precision: /* empty */ {} @@ -1171,11 +1206,14 @@ attribute: | NOT NULL_SYM { Lex->type|= NOT_NULL_FLAG; } | DEFAULT literal { Lex->default_value=$2; } | AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; } - | PRIMARY_SYM KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; } + | SERIAL_SYM DEFAULT VALUE_SYM + { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; } + | 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; }; + charset_name: BINARY { @@ -1209,9 +1247,15 @@ opt_db_default_character_set: opt_binary: /* empty */ { Lex->charset=NULL; } + | BYTE_SYM { Lex->charset=my_charset_bin; } | BINARY { Lex->charset=my_charset_bin; } | CHAR_SYM SET charset_name { Lex->charset=$3; } ; + +opt_primary: + /* empty */ + | PRIMARY_SYM + references: REFERENCES table_ident { @@ -1443,20 +1487,24 @@ opt_to: | EQ {} | AS {}; +/* + The first two deprecate the last two--delete the last two for 4.1 release +*/ + slave: START_SYM SLAVE slave_thread_opts - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_SLAVE_START; - lex->type = 0; - } - | - STOP_SYM SLAVE slave_thread_opts - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_SLAVE_STOP; - lex->type = 0; - }; + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_START; + lex->type = 0; + } + | STOP_SYM SLAVE slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_STOP; + lex->type = 0; + } + ; slave_thread_opts: slave_thread_opt @@ -1609,14 +1657,16 @@ select_init: select_part2: { LEX *lex=Lex; - lex->lock_option=TL_READ; - mysql_init_select(lex); + if (lex->current_select == &lex->select_lex) + lex->lock_option= TL_READ; /* Only for global SELECT */ + mysql_init_select(lex); } select_options select_item_list select_into select_lock_type; select_into: limit_clause {} | select_from + | FROM DUAL_SYM | opt_into | opt_into select_from | select_from opt_into; @@ -1656,7 +1706,7 @@ select_option: YYABORT; Select->options|= OPTION_FOUND_ROWS; } - | SQL_NO_CACHE_SYM { current_thd->safe_to_cache_query=0; } + | SQL_NO_CACHE_SYM { Lex->safe_to_cache_query=0; } | SQL_CACHE_SYM { Select->options|= OPTION_TO_QUERY_CACHE; } | ALL {} ; @@ -1666,18 +1716,15 @@ select_lock_type: | FOR_SYM UPDATE_SYM { LEX *lex=Lex; - if (check_simple_select()) - YYABORT; - lex->lock_option= TL_WRITE; - lex->thd->safe_to_cache_query=0; + lex->current_select->set_lock_for_tables(TL_WRITE); + lex->safe_to_cache_query=0; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { LEX *lex=Lex; - if (check_simple_select()) - YYABORT; - lex->lock_option= TL_READ_WITH_SHARED_LOCKS; - lex->thd->safe_to_cache_query=0; + lex->current_select-> + set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS); + lex->safe_to_cache_query=0; } ; @@ -1782,6 +1829,8 @@ expr_expr: | expr '-' expr { $$= new Item_func_minus($1,$3); } | expr '*' expr { $$= new Item_func_mul($1,$3); } | expr '/' expr { $$= new Item_func_div($1,$3); } + | expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); } + | expr MOD_SYM expr { $$= new Item_func_mod($1,$3); } | expr '|' expr { $$= new Item_func_bit_or($1,$3); } | expr '^' expr { $$= new Item_func_bit_xor($1,$3); } | expr '&' expr { $$= new Item_func_bit_and($1,$3); } @@ -1826,10 +1875,12 @@ no_in_expr: | no_in_expr '-' expr { $$= new Item_func_minus($1,$3); } | no_in_expr '*' expr { $$= new Item_func_mul($1,$3); } | no_in_expr '/' expr { $$= new Item_func_div($1,$3); } + | no_in_expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); } | no_in_expr '|' expr { $$= new Item_func_bit_or($1,$3); } | no_in_expr '^' expr { $$= new Item_func_bit_xor($1,$3); } | no_in_expr '&' expr { $$= new Item_func_bit_and($1,$3); } | no_in_expr '%' expr { $$= new Item_func_mod($1,$3); } + | no_in_expr MOD_SYM expr { $$= new Item_func_mod($1,$3); } | no_in_expr '+' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,0); } | no_in_expr '-' INTERVAL_SYM expr interval @@ -1878,10 +1929,12 @@ no_and_expr: | no_and_expr '-' expr { $$= new Item_func_minus($1,$3); } | no_and_expr '*' expr { $$= new Item_func_mul($1,$3); } | no_and_expr '/' expr { $$= new Item_func_div($1,$3); } + | no_and_expr DIV_SYM expr { $$= new Item_func_int_div($1,$3); } | no_and_expr '|' expr { $$= new Item_func_bit_or($1,$3); } | no_and_expr '^' expr { $$= new Item_func_bit_xor($1,$3); } | no_and_expr '&' expr { $$= new Item_func_bit_and($1,$3); } | no_and_expr '%' expr { $$= new Item_func_mod($1,$3); } + | no_and_expr MOD_SYM expr { $$= new Item_func_mod($1,$3); } | no_and_expr '+' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,0); } | no_and_expr '-' INTERVAL_SYM expr interval @@ -1895,12 +1948,12 @@ simple_expr: | '@' ident_or_text SET_VAR expr { $$= new Item_func_set_user_var($2,$4); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | '@' ident_or_text { $$= new Item_func_get_user_var($2); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | '@' '@' opt_var_ident_type ident_or_text { @@ -1954,13 +2007,13 @@ simple_expr: | CONCAT_WS '(' expr ',' expr_list ')' { $$= new Item_func_concat_ws($3, *$5); } | CURDATE optional_braces - { $$= new Item_func_curdate(); current_thd->safe_to_cache_query=0; } + { $$= new Item_func_curdate(); Lex->safe_to_cache_query=0; } | CURTIME optional_braces - { $$= new Item_func_curtime(); current_thd->safe_to_cache_query=0; } + { $$= new Item_func_curtime(); Lex->safe_to_cache_query=0; } | CURTIME '(' expr ')' { $$= new Item_func_curtime($3); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new Item_date_add_interval($3,$6,$7,0); } @@ -1969,7 +2022,7 @@ simple_expr: | DATABASE '(' ')' { $$= new Item_func_database(); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | ELT_FUNC '(' expr ',' expr_list ')' { $$= new Item_func_elt($3, *$5); } @@ -1978,7 +2031,7 @@ simple_expr: | ENCRYPT '(' expr ')' { $$= new Item_func_encrypt($3); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | ENCRYPT '(' expr ',' expr ')' { $$= new Item_func_encrypt($3,$5); } | DECODE_SYM '(' expr ',' TEXT_STRING ')' @@ -1999,6 +2052,8 @@ simple_expr: { $$= new Item_func_export_set($3, $5, $7, $9); } | EXPORT_SET '(' expr ',' expr ',' expr ',' expr ',' expr ')' { $$= new Item_func_export_set($3, $5, $7, $9, $11); } + | FALSE_SYM + { $$= new Item_int((char*) "FALSE",0,1); } | FORMAT_SYM '(' expr ',' NUM ')' { $$= new Item_func_format($3,atoi($5.str)); } | FROM_UNIXTIME '(' expr ')' @@ -2036,7 +2091,7 @@ simple_expr: | LAST_INSERT_ID '(' expr ')' { $$= new Item_func_set_last_insert_id($3); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | LEFT '(' expr ',' expr ')' { $$= new Item_func_left($3,$5); } @@ -2065,6 +2120,8 @@ simple_expr: { $$= new Item_func_geometry_from_text($3); } | MINUTE_SYM '(' expr ')' { $$= new Item_func_minute($3); } + | MOD_SYM '(' expr ',' expr ')' + { $$ = new Item_func_mod( $3, $5); } | MONTH_SYM '(' expr ')' { $$= new Item_func_month($3); } | MULTILINESTRING '(' expr_list ')' @@ -2089,9 +2146,9 @@ simple_expr: { $$= new Item_func_spatial_collection(* $3, Geometry::wkbMultiPolygon, Geometry::wkbPolygon ); } | NOW_SYM optional_braces - { $$= new Item_func_now(); current_thd->safe_to_cache_query=0;} + { $$= new Item_func_now(); Lex->safe_to_cache_query=0;} | NOW_SYM '(' expr ')' - { $$= new Item_func_now($3); current_thd->safe_to_cache_query=0;} + { $$= new Item_func_now($3); Lex->safe_to_cache_query=0;} | PASSWORD '(' expr ')' { $$= new Item_func_password($3); @@ -2110,9 +2167,9 @@ simple_expr: | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } | RAND '(' expr ')' - { $$= new Item_func_rand($3); current_thd->safe_to_cache_query=0;} + { $$= new Item_func_rand($3); Lex->safe_to_cache_query=0;} | RAND '(' ')' - { $$= new Item_func_rand(); current_thd->safe_to_cache_query=0;} + { $$= new Item_func_rand(); Lex->safe_to_cache_query=0;} | REPLACE '(' expr ',' expr ',' expr ')' { $$= new Item_func_replace($3,$5,$7); } | RIGHT '(' expr ',' expr ')' @@ -2144,6 +2201,8 @@ simple_expr: { $$= new Item_func_trim($5,$3); } | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,1); } + | TRUE_SYM + { $$= new Item_int((char*) "TRUE",1,1); } | UDA_CHAR_SUM '(' udf_expr_list ')' { if ($3 != NULL) @@ -2193,12 +2252,12 @@ simple_expr: | UNIX_TIMESTAMP '(' ')' { $$= new Item_func_unix_timestamp(); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | UNIX_TIMESTAMP '(' expr ')' { $$= new Item_func_unix_timestamp($3); } | USER '(' ')' - { $$= new Item_func_user(); current_thd->safe_to_cache_query=0; } + { $$= new Item_func_user(); Lex->safe_to_cache_query=0; } | WEEK_SYM '(' expr ')' { $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); } | WEEK_SYM '(' expr ',' expr ')' @@ -2212,7 +2271,7 @@ simple_expr: | BENCHMARK_SYM '(' ULONG_NUM ',' expr ')' { $$=new Item_func_benchmark($3,$5); - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new Item_extract( $3, $5); }; @@ -2262,13 +2321,15 @@ in_sum_expr: cast_type: BINARY { $$=ITEM_CAST_BINARY; } + | CHAR_SYM { $$=ITEM_CAST_CHAR; } | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; } | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; } | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; } | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; } | DATE_SYM { $$=ITEM_CAST_DATE; } | TIME_SYM { $$=ITEM_CAST_TIME; } - | DATETIME { $$=ITEM_CAST_DATETIME; }; + | DATETIME { $$=ITEM_CAST_DATETIME; } + ; expr_list: { Select->expr_list.push_front(new List<Item>); } @@ -2378,8 +2439,9 @@ join_table: } table_ident opt_table_alias opt_key_definition { - SELECT_LEX_NODE *sel=Select; - if (!($$= sel->add_table_to_list($2, $3, 0, TL_UNLOCK, + LEX *lex= Lex; + SELECT_LEX_NODE *sel= lex->current_select; + if (!($$= sel->add_table_to_list($2, $3, 0, lex->lock_option, sel->get_use_index(), sel->get_ignore_index()))) YYABORT; @@ -2392,7 +2454,8 @@ join_table: SELECT_LEX_UNIT *unit= lex->current_select->master_unit(); lex->current_select= unit->outer_select(); if (!($$= lex->current_select-> - add_table_to_list(new Table_ident(unit), $5, 0, TL_UNLOCK))) + add_table_to_list(new Table_ident(unit), $5, 0, + lex->lock_option))) YYABORT; }; @@ -2495,15 +2558,24 @@ opt_table_alias: where_clause: /* empty */ { Select->select_lex()->where= 0; } - | WHERE expr { Select->select_lex()->where= $2; }; + | WHERE expr + { + Select->select_lex()->where= $2; + if ($2) + $2->top_level_item(); + } + ; having_clause: /* empty */ | HAVING { Select->select_lex()->create_refs= 1; } expr - { - SELECT_LEX *sel= Select->select_lex(); - sel->having= $3; sel->create_refs=0; - }; + { + SELECT_LEX *sel= Select->select_lex(); + sel->having= $3; sel->create_refs=0; + if ($3) + $3->top_level_item(); + } + ; opt_escape: ESCAPE_SYM TEXT_STRING { $$= $2.str; } @@ -2568,11 +2640,6 @@ order_clause: ORDER_SYM BY { LEX *lex=Lex; - if (lex->sql_command == SQLCOM_MULTI_UPDATE) - { - net_printf(lex->thd, ER_WRONG_USAGE, "UPDATE", "ORDER BY"); - YYABORT; - } if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && lex->current_select->select_lex()->olap != UNSPECIFIED_OLAP_TYPE) @@ -2598,7 +2665,7 @@ order_dir: limit_clause: /* empty */ {} - | LIMIT ULONG_NUM + | LIMIT { LEX *lex= Lex; if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && @@ -2609,35 +2676,36 @@ limit_clause: "LIMIT"); YYABORT; } + } + limit_options + ; + +limit_options: + ULONG_NUM + { + SELECT_LEX_NODE *sel= Select; + sel->select_limit= $1; + sel->offset_limit= 0L; + } + | ULONG_NUM ',' ULONG_NUM + { SELECT_LEX_NODE *sel= Select; - sel->select_limit= $2; - sel->offset_limit= 0L; + sel->select_limit= $3; + sel->offset_limit= $1; } - | LIMIT ULONG_NUM ',' ULONG_NUM + | ULONG_NUM OFFSET_SYM ULONG_NUM { - LEX *lex=Lex; - if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && - lex->current_select->select_lex()->olap != - UNSPECIFIED_OLAP_TYPE) - { - net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", - "LIMIT"); - YYABORT; - } - SELECT_LEX_NODE *sel= lex->current_select; - sel->select_limit= $4; - sel->offset_limit= $2; - }; + SELECT_LEX_NODE *sel= Select; + sel->select_limit= $1; + sel->offset_limit= $3; + } + ; + delete_limit_clause: /* empty */ { LEX *lex=Lex; - if (lex->sql_command == SQLCOM_MULTI_UPDATE) - { - net_printf(lex->thd, ER_WRONG_USAGE, "DELETE", "LIMIT"); - YYABORT; - } lex->current_select->select_limit= HA_POS_ERROR; } | LIMIT ulonglong_num @@ -2666,7 +2734,7 @@ procedure_clause: lex->proc_list.next= (byte**) &lex->proc_list.first; if (add_proc_to_list(new Item_field(NULL,NULL,$2.str))) YYABORT; - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } '(' procedure_list ')'; @@ -2738,7 +2806,7 @@ opt_into: } | INTO select_var_list_init { - current_thd->safe_to_cache_query=0; + Lex->safe_to_cache_query=0; } ; @@ -2759,11 +2827,12 @@ do: DO_SYM */ drop: - DROP TABLE_SYM if_exists table_list opt_restrict + DROP opt_temporary TABLE_SYM if_exists table_list opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_TABLE; - lex->drop_if_exists = $3; + lex->drop_temporary= $2; + lex->drop_if_exists= $4; } | DROP INDEX ident ON table_ident {} { @@ -2799,15 +2868,32 @@ table_name: { if (!Select->add_table_to_list($1, NULL, 1)) YYABORT; }; if_exists: - /* empty */ { $$=0; } - | IF EXISTS { $$= 1; }; + /* empty */ { $$= 0; } + | IF EXISTS { $$= 1; } + ; +opt_temporary: + /* empty */ { $$= 0; } + | TEMPORARY { $$= 1; } + ; /* ** Insert : add new data to table */ insert: - INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option opt_ignore insert2 insert_field_spec; + INSERT + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_INSERT; + /* for subselects */ + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + } insert_lock_option + opt_ignore insert2 + { + Select->set_lock_for_tables($3); + } + insert_field_spec + ; replace: REPLACE @@ -2816,17 +2902,23 @@ replace: lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; } - replace_lock_option insert2 insert_field_spec; + replace_lock_option insert2 + { + Select->set_lock_for_tables($3); + } + insert_field_spec + ; insert_lock_option: - /* empty */ { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } - | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; } - | HIGH_PRIORITY { Lex->lock_option= TL_WRITE; }; + /* empty */ { $$= TL_WRITE_CONCURRENT_INSERT; } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } + | DELAYED_SYM { $$= TL_WRITE_DELAYED; } + | HIGH_PRIORITY { $$= TL_WRITE; } + ; replace_lock_option: - opt_low_priority {} - | DELAYED_SYM { Lex->lock_option= TL_WRITE_DELAYED; }; + opt_low_priority { $$= $1; } + | DELAYED_SYM { $$= TL_WRITE_DELAYED; }; insert2: INTO insert_table {} @@ -2863,6 +2955,7 @@ fields: insert_values: VALUES values_list {} + | VALUE_SYM values_list {} | SELECT_SYM { LEX *lex=Lex; @@ -2872,7 +2965,8 @@ insert_values: mysql_init_select(lex); } select_options select_item_list select_from select_lock_type - union {}; + union {} + ; values_list: values_list ',' no_braces @@ -2939,13 +3033,18 @@ expr_or_default: /* Update rows in a table */ update: - UPDATE_SYM + UPDATE_SYM { LEX *lex= Lex; lex->sql_command= SQLCOM_UPDATE; lex->select_lex.init_order(); } - opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause; + opt_low_priority opt_ignore join_table_list + SET update_list where_clause opt_order_clause delete_limit_clause + { + Select->set_lock_for_tables($3); + } + ; update_list: update_list ',' simple_ident equal expr @@ -2960,8 +3059,8 @@ update_list: }; opt_low_priority: - /* empty */ { Lex->lock_option= current_thd->update_lock_default; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + /* empty */ { $$= current_thd->update_lock_default; } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; /* Delete rows from a table */ @@ -2974,13 +3073,20 @@ delete: lex->lock_option= lex->thd->update_lock_default; lex->select_lex.init_order(); } - opt_delete_options single_multi {}; + opt_delete_options single_multi {} + ; single_multi: - FROM table_name where_clause opt_order_clause delete_limit_clause {} + FROM table_ident + { + if (!Select->add_table_to_list($2, NULL, 1, Lex->lock_option)) + YYABORT; + } + where_clause opt_order_clause + delete_limit_clause | table_wild_list { mysql_init_multi_delete(Lex); } - FROM join_table_list where_clause + FROM join_table_list where_clause | FROM table_wild_list { mysql_init_multi_delete(Lex); } USING join_table_list where_clause; @@ -2990,18 +3096,19 @@ table_wild_list: | table_wild_list ',' table_wild_one {}; table_wild_one: - ident opt_wild - { - if (!Select->add_table_to_list(new Table_ident($1), NULL, 1, - TL_WRITE)) - YYABORT; - } - | ident '.' ident opt_wild - { - if (!Select->add_table_to_list(new Table_ident($1, $3, 0), NULL, - 1, TL_WRITE)) + ident opt_wild + { + if (!Select->add_table_to_list(new Table_ident($1), NULL, 1, + Lex->lock_option)) + YYABORT; + } + | ident '.' ident opt_wild + { + if (!Select->add_table_to_list(new Table_ident($1, $3, 0), NULL, 1, + Lex->lock_option)) YYABORT; - }; + } + ; opt_wild: /* empty */ {} @@ -3023,7 +3130,8 @@ truncate: lex->sql_command= SQLCOM_TRUNCATE; lex->select_lex.options= 0; lex->select_lex.init_order(); - lex->lock_option= lex->thd->update_lock_default; }; + } + ; opt_table_sym: /* empty */ @@ -3315,7 +3423,8 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING { LEX *lex=Lex; lex->sql_command= SQLCOM_LOAD; - lex->local_file= $4; + lex->lock_option= $3; + lex->local_file= $4; if (!(lex->exchange= new sql_exchange($6.str,0))) YYABORT; lex->field_list.empty(); @@ -3345,9 +3454,9 @@ opt_local: | LOCAL_SYM { $$=1;}; load_data_lock: - /* empty */ { Lex->lock_option= current_thd->update_lock_default; } - | CONCURRENT { Lex->lock_option= TL_WRITE_CONCURRENT_INSERT ; } - | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; }; + /* empty */ { $$= current_thd->update_lock_default; } + | CONCURRENT { $$= TL_WRITE_CONCURRENT_INSERT ; } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; opt_duplicate: @@ -3490,12 +3599,13 @@ ident: IDENT { $$=$1; } | keyword { - LEX *lex; - $$.str=sql_strmake($1.str,$1.length); + LEX *lex= Lex; + $$.str= lex->thd->strmake($1.str,$1.length); $$.length=$1.length; - if ((lex=Lex)->next_state != STATE_END) + if (lex->next_state != STATE_END) lex->next_state=STATE_OPERATOR_OR_IDENT; - }; + } + ; ident_or_text: ident { $$=$1;} @@ -3534,11 +3644,11 @@ keyword: | BIT_SYM {} | BOOL_SYM {} | BOOLEAN_SYM {} + | BYTE_SYM {} | CACHE_SYM {} | CHANGED {} | CHARSET {} | CHECKSUM_SYM {} - | CHECK_SYM {} | CIPHER_SYM {} | CLIENT_SYM {} | CLOSE_SYM {} @@ -3557,6 +3667,7 @@ keyword: | DIRECTORY_SYM {} | DO_SYM {} | DUMPFILE {} + | DUAL_SYM {} | DYNAMIC_SYM {} | END {} | ENUM {} @@ -3617,6 +3728,7 @@ keyword: | NEW_SYM {} | NO_SYM {} | NONE_SYM {} + | OFFSET_SYM {} | OPEN_SYM {} | PACK_KEYS_SYM {} | PARTIAL {} @@ -3646,6 +3758,7 @@ keyword: | ROW_FORMAT_SYM {} | ROW_SYM {} | SECOND_SYM {} + | SERIAL_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} | SIGNED_SYM {} @@ -3674,6 +3787,7 @@ keyword: | UNCOMMITTED_SYM {} | USE_FRM {} | VARIABLES {} + | VALUE_SYM {} | WORK_SYM {} | YEAR_SYM {} ; @@ -4200,7 +4314,7 @@ rollback: */ -union: +union: /* empty */ {} |UNION_SYM union_option { @@ -4224,11 +4338,15 @@ union: ; union_opt: - union {} - | optional_order_or_limit {}; + union_list {} + | optional_order_or_limit {} + ; optional_order_or_limit: - /* empty */ {} + /* empty + intentional reduce/reduce conflict here !!! + { code } below should not be executed + when neither ORDER BY nor LIMIT are used */ {} | { LEX *lex=Lex; |