diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 642 |
1 files changed, 350 insertions, 292 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c6fa32d8117..49ca047e89b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -289,7 +289,7 @@ int LEX::case_stmt_action_then() bool LEX::set_system_variable(enum enum_var_type var_type, - sys_var *sysvar, const LEX_CSTRING *base_name, + sys_var *sysvar, const Lex_ident_sys_st *base_name, Item *val) { set_var *setvar; @@ -299,7 +299,7 @@ LEX::set_system_variable(enum enum_var_type var_type, sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; if (val && val->type() == Item::FIELD_ITEM && - ((Item_field*)val)->table_name) + ((Item_field*)val)->table_name.str) { my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), sysvar->name.str); return TRUE; @@ -339,7 +339,7 @@ bool LEX::set_trigger_new_row(const LEX_CSTRING *name, Item *val) trg_fld= new (thd->mem_root) Item_trigger_field(thd, current_context(), Item_trigger_field::NEW_ROW, - name, UPDATE_ACL, FALSE); + *name, UPDATE_ACL, FALSE); if (unlikely(trg_fld == NULL)) return TRUE; @@ -506,34 +506,22 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, @see sp_create_assignment_instr @param thd Thread context - @param no_lookahead True if the parser has no lookahead + @param pos The position in the raw SQL buffer */ -void sp_create_assignment_lex(THD *thd, bool no_lookahead) -{ - LEX *lex= thd->lex; - if (lex->sphead) +bool sp_create_assignment_lex(THD *thd, const char *pos) +{ + if (thd->lex->sphead) { - Lex_input_stream *lip= &thd->m_parser_state->m_lip; - LEX *old_lex= lex; - lex->sphead->reset_lex(thd); - lex= thd->lex; - - /* Set new LEX as if we at start of set rule. */ - lex->sql_command= SQLCOM_SET_OPTION; - mysql_init_select(lex); - lex->var_list.empty(); - lex->autocommit= 0; - /* get_ptr() is only correct with no lookahead. */ - if (no_lookahead) - lex->sphead->m_tmp_query= lip->get_ptr(); - else - lex->sphead->m_tmp_query= lip->get_tok_end(); - /* Inherit from outer lex. */ - lex->option_type= old_lex->option_type; - lex->main_select_push(); + sp_lex_local *new_lex; + if (!(new_lex= new (thd->mem_root) sp_lex_set_var(thd, thd->lex)) || + new_lex->main_select_push()) + return true; + new_lex->sphead->m_tmp_query= pos; + return thd->lex->sphead->reset_lex(thd, new_lex); } + return false; } @@ -542,13 +530,15 @@ void sp_create_assignment_lex(THD *thd, bool no_lookahead) @see sp_create_assignment_lex - @param thd Thread context - @param no_lookahead True if the parser has no lookahead - + @param thd - Thread context + @param no_lookahead - True if the parser has no lookahead + @param need_set_keyword - if a SET statement "SET a=10", + or a direct assignment overwise "a:=10" @return false if success, true otherwise. */ -bool sp_create_assignment_instr(THD *thd, bool no_lookahead) +bool sp_create_assignment_instr(THD *thd, bool no_lookahead, + bool need_set_keyword) { LEX *lex= thd->lex; @@ -557,6 +547,24 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) if (!lex->var_list.is_empty()) { /* + - Every variable assignment from the same SET command, e.g.: + SET @var1=expr1, @var2=expr2; + produce each own sp_create_assignment_instr() call + lex->var_list.elements is 1 in this case. + - This query: + SET TRANSACTION READ ONLY, ISOLATION LEVEL SERIALIZABLE; + in translated to: + SET tx_read_only=1, tx_isolation=ISO_SERIALIZABLE; + but produces a single sp_create_assignment_instr() call + which includes the query fragment covering both options. + */ + DBUG_ASSERT(lex->var_list.elements >= 1 && lex->var_list.elements <= 2); + /* + sql_mode=ORACLE's direct assignment of a global variable + is not possible by the grammar. + */ + DBUG_ASSERT(Lex->option_type != OPT_GLOBAL || need_set_keyword); + /* We have assignment to user or system variable or option setting, so we should construct sp_instr_stmt for it. @@ -568,10 +576,15 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) end is either lip->ptr, if there was no lookahead, lip->tok_end otherwise. */ - static const LEX_CSTRING setsp= { STRING_WITH_LEN("SET ") }; + static const LEX_CSTRING setlc= { STRING_WITH_LEN("SET ") }; + static const LEX_CSTRING setgl= { STRING_WITH_LEN("SET GLOBAL ") }; const char *qend= no_lookahead ? lip->get_ptr() : lip->get_tok_end(); Lex_cstring qbuf(lex->sphead->m_tmp_query, qend); - if (lex->new_sp_instr_stmt(thd, setsp, qbuf)) + if (lex->new_sp_instr_stmt(thd, + Lex->option_type == OPT_GLOBAL ? setgl : + need_set_keyword ? setlc : + null_clex_str, + qbuf)) return true; } lex->pop_select(); @@ -779,7 +792,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) enum Condition_information_item::Name cond_info_item_name; enum enum_diag_condition_item_name diag_condition_item_name; enum Diagnostics_information::Which_area diag_area; - enum Field::geometry_type geom_type; enum enum_fk_option m_fk_option; enum Item_udftype udf_type; enum Key::Keytype key_type; @@ -817,10 +829,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 47 shift/reduce conflicts. + Currently there are 46 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 47 +%expect 46 /* Comments for TOKENS. @@ -842,6 +854,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); */ +%token <lex_str> '@' + /* Reserved keywords and operators */ @@ -874,7 +888,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ %token CHANGE -%token CHAR_SYM /* SQL-2003-R */ +%token <kwd> CHAR_SYM /* SQL-2003-R */ %token CHECK_SYM /* SQL-2003-R */ %token COLLATE_SYM /* SQL-2003-R */ %token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ @@ -903,7 +917,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_MARIADB_SYM /* SQL-2003-R */ %token DECLARE_ORACLE_SYM /* Oracle-R */ -%token DEFAULT /* SQL-2003-R */ +%token <kwd> DEFAULT /* SQL-2003-R */ %token DELETE_DOMAIN_ID_SYM %token DELETE_SYM /* SQL-2003-R */ %token DENSE_RANK_SYM @@ -1308,8 +1322,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> FUNCTION_SYM /* SQL-2003-R, Oracle-R */ %token <kwd> GENERAL %token <kwd> GENERATED_SYM -%token <kwd> GEOMETRYCOLLECTION -%token <kwd> GEOMETRY_SYM %token <kwd> GET_FORMAT /* MYSQL-FUNC */ %token <kwd> GET_SYM /* SQL-2003-R */ %token <kwd> GLOBAL_SYM /* SQL-2003-R */ @@ -1349,7 +1361,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> LEAVES %token <kwd> LESS_SYM %token <kwd> LEVEL_SYM -%token <kwd> LINESTRING %token <kwd> LIST_SYM %token <kwd> LOCAL_SYM /* SQL-2003-R */ %token <kwd> LOCKS_SYM @@ -1395,9 +1406,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> MODE_SYM %token <kwd> MODIFY_SYM %token <kwd> MONTH_SYM /* SQL-2003-R */ -%token <kwd> MULTILINESTRING -%token <kwd> MULTIPOINT -%token <kwd> MULTIPOLYGON %token <kwd> MUTEX_SYM %token <kwd> MYSQL_SYM %token <kwd> MYSQL_ERRNO_SYM @@ -1444,8 +1452,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %token <kwd> PHASE_SYM %token <kwd> PLUGINS_SYM %token <kwd> PLUGIN_SYM -%token <kwd> POINT_SYM -%token <kwd> POLYGON %token <kwd> PORT_SYM %token <kwd> PRECEDES_SYM /* MYSQL */ %token <kwd> PRECEDING_SYM /* SQL-2011-N */ @@ -1702,7 +1708,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); and until NEXT_SYM / PREVIOUS_SYM. */ %left PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE -%left TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM USER +%left TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM USER COMMENT_SYM /* @@ -1748,7 +1754,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ident label_ident sp_decl_ident - ident_set_usual_case ident_or_empty ident_table_alias ident_sysvar_name @@ -1766,6 +1771,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); IDENT_QUOTED IDENT_cli ident_cli + ident_cli_set_usual_case %type <kwd> keyword_data_type @@ -1782,6 +1788,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); keyword_sysvar_type keyword_table_alias keyword_verb_clause + charset %type <table> table_ident table_ident_nodb references xid @@ -1816,8 +1823,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type <create_field> field_spec column_def -%type <geom_type> spatial_type - %type <num> order_dir lock_option udf_type opt_local opt_no_write_to_binlog @@ -1859,6 +1864,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ws_level_flag_desc ws_level_flag_reverse ws_level_flags opt_ws_levels ws_level_list ws_level_list_item ws_level_number ws_level_range ws_level_list_or_range bool + field_options last_field_options %type <ulonglong_number> ulonglong_num real_ulonglong_num size_number @@ -1880,7 +1886,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); primary_expr string_factor_expr mysql_concatenation_expr select_sublist_qualified_asterisk expr_or_default set_expr_or_default - geometry_function signed_literal expr_or_literal + signed_literal expr_or_literal opt_escape sp_opt_default simple_ident_nospvar @@ -2054,7 +2060,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); procedure_list procedure_list2 procedure_item field_def handler opt_generated_always opt_ignore opt_column opt_restrict - grant revoke set lock unlock string_list field_options + grant revoke set lock unlock string_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar @@ -2073,7 +2079,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); 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 - opt_and charset + opt_and select_var_list select_var_list_init help opt_extended_describe shutdown opt_format_json @@ -2799,6 +2805,7 @@ create: | create_or_replace DATABASE opt_if_not_exists ident { Lex->create_info.default_table_charset= NULL; + Lex->create_info.schema_comment= NULL; Lex->create_info.used_fields= 0; if (Lex->main_select_push()) MYSQL_YYABORT; @@ -6035,6 +6042,11 @@ create_database_options: create_database_option: default_collation {} | default_charset {} + | COMMENT_SYM opt_equal TEXT_STRING_sys + { + Lex->create_info.schema_comment= thd->make_clex_string($3); + Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; + } ; opt_if_not_exists_table_element: @@ -6649,7 +6661,7 @@ field_type_or_serial: field_def | SERIAL_SYM { - Lex->last_field->set_handler(&type_handler_longlong); + Lex->last_field->set_handler(&type_handler_ulonglong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; } @@ -6820,12 +6832,23 @@ field_type: | field_type_string | field_type_lob | field_type_misc + | IDENT_sys float_options srid_option + { + const Type_handler *h; + if (!(h= Type_handler::handler_by_name_or_error($1))) + MYSQL_YYABORT; + $$.set(h, $2); + Lex->charset= &my_charset_bin; + } ; field_type_numeric: - int_type opt_field_length field_options { $$.set($1, $2); } - | real_type opt_precision field_options { $$.set($1, $2); } - | FLOAT_SYM float_options field_options + int_type opt_field_length last_field_options + { + $$.set_handler_length_flags($1, $2, (uint32) $3); + } + | real_type opt_precision last_field_options { $$.set($1, $2); } + | FLOAT_SYM float_options last_field_options { $$.set(&type_handler_float, $2); if ($2.length() && !$2.dec()) @@ -6847,24 +6870,24 @@ field_type_numeric: } | BOOL_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } | BOOLEAN_SYM { - $$.set(&type_handler_tiny, "1"); + $$.set(&type_handler_stiny, "1"); } - | DECIMAL_SYM float_options field_options + | DECIMAL_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | NUMBER_ORACLE_SYM float_options field_options + | NUMBER_ORACLE_SYM float_options last_field_options { if ($2.length() != 0) $$.set(&type_handler_newdecimal, $2); else $$.set(&type_handler_double); } - | NUMERIC_SYM float_options field_options + | NUMERIC_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} - | FIXED_SYM float_options field_options + | FIXED_SYM float_options last_field_options { $$.set(&type_handler_newdecimal, $2);} ; @@ -6917,7 +6940,7 @@ field_type_string: ; field_type_temporal: - YEAR_SYM opt_field_length field_options + YEAR_SYM opt_field_length last_field_options { if ($2) { @@ -6995,17 +7018,6 @@ field_type_lob: Lex->charset=&my_charset_bin; $$.set(&type_handler_long_blob); } - | spatial_type float_options srid_option - { -#ifdef HAVE_SPATIAL - Lex->charset=&my_charset_bin; - Lex->last_field->geom_type= $1; - $$.set(&type_handler_geometry, $2); -#else - my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, - sym_group_geom.needed_define)); -#endif - } | MEDIUMBLOB opt_compressed { Lex->charset=&my_charset_bin; @@ -7049,17 +7061,6 @@ field_type_misc: { $$.set(&type_handler_set); } ; -spatial_type: - GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } - | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } - | POINT_SYM { $$= Field::GEOM_POINT; } - | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } - | LINESTRING { $$= Field::GEOM_LINESTRING; } - | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } - | POLYGON { $$= Field::GEOM_POLYGON; } - | MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; } - ; - char: CHAR_SYM {} ; @@ -7083,11 +7084,11 @@ nvarchar: ; int_type: - INT_SYM { $$= &type_handler_long; } - | TINYINT { $$= &type_handler_tiny; } - | SMALLINT { $$= &type_handler_short; } - | MEDIUMINT { $$= &type_handler_int24; } - | BIGINT { $$= &type_handler_longlong; } + INT_SYM { $$= &type_handler_slong; } + | TINYINT { $$= &type_handler_stiny; } + | SMALLINT { $$= &type_handler_sshort; } + | MEDIUMINT { $$= &type_handler_sint24; } + | BIGINT { $$= &type_handler_slonglong; } ; real_type: @@ -7122,12 +7123,16 @@ precision: ; field_options: - /* empty */ {} - | SIGNED_SYM {} - | UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;} - | ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } - | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; } + /* empty */ { $$= 0; } + | SIGNED_SYM { $$= 0; } + | UNSIGNED { $$= UNSIGNED_FLAG; } + | ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | UNSIGNED ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + | ZEROFILL UNSIGNED { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; } + ; + +last_field_options: + field_options { Lex->last_field->flags|= ($$= $1); } ; field_length: @@ -7308,8 +7313,8 @@ type_with_opt_collate: ; charset: - CHAR_SYM SET {} - | CHARSET {} + CHAR_SYM SET { $$= $1; } + | CHARSET { $$= $1; } ; charset_name: @@ -7800,6 +7805,7 @@ alter: | ALTER DATABASE ident_or_empty { Lex->create_info.default_table_charset= NULL; + Lex->create_info.schema_comment= NULL; Lex->create_info.used_fields= 0; if (Lex->main_select_push()) MYSQL_YYABORT; @@ -7814,6 +7820,22 @@ alter: MYSQL_YYABORT; Lex->pop_select(); //main select } + | ALTER DATABASE COMMENT_SYM opt_equal TEXT_STRING_sys + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + Lex->create_info.schema_comment= thd->make_clex_string($5); + Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; + } + opt_create_database_options + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_ALTER_DB; + lex->name= Lex_ident_sys(); + if (lex->name.str == NULL && + unlikely(lex->copy_db_to(&lex->name))) + MYSQL_YYABORT; + } | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM { LEX *lex= Lex; @@ -8058,7 +8080,8 @@ opt_ev_sql_stmt: ; ident_or_empty: - /* empty */ { $$= Lex_ident_sys(); } + /* empty */ + %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE { $$= Lex_ident_sys(); } | ident ; @@ -9567,7 +9590,7 @@ select_item_list: { Item *item= new (thd->mem_root) Item_field(thd, &thd->lex->current_select->context, - NULL, NULL, &star_clex_str); + star_clex_str); if (unlikely(item == NULL)) MYSQL_YYABORT; if (unlikely(add_item_to_list(thd, item))) @@ -9594,7 +9617,7 @@ select_item: check_column_name($4.str))) my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), $4.str)); $2->is_autogenerated_name= FALSE; - $2->set_name(thd, $4.str, $4.length, system_charset_info); + $2->set_name(thd, $4); } else if (!$2->name.str || $2->name.str == item_empty_name) { @@ -10272,7 +10295,8 @@ column_default_non_parenthesized_expr: } | CAST_SYM '(' expr AS cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CASE_SYM when_list_opt_else END @@ -10288,7 +10312,8 @@ column_default_non_parenthesized_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - if (unlikely(!($$= $5.create_typecast_item(thd, $3, Lex->charset)))) + if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3, + Lex->charset)))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' @@ -10996,78 +11021,6 @@ function_call_conflict: if (unlikely($$ == NULL)) MYSQL_YYABORT; } - | geometry_function - { -#ifdef HAVE_SPATIAL - $$= $1; - /* $1 may be NULL, GEOM_NEW not tested for out of memory */ - if (unlikely($$ == NULL)) - MYSQL_YYABORT; -#else - my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, - sym_group_geom.needed_define)); -#endif - } - ; - -geometry_function: - CONTAINS_SYM '(' expr ',' expr ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_precise_rel(thd, $3, $5, - Item_func::SP_CONTAINS_FUNC)); - } - | GEOMETRYCOLLECTION '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_geometrycollection, - Geometry::wkb_point)); - } - | LINESTRING '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_linestring, - Geometry::wkb_point)); - } - | MULTILINESTRING '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_multilinestring, - Geometry::wkb_linestring)); - } - | MULTIPOINT '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_multipoint, - Geometry::wkb_point)); - } - | MULTIPOLYGON '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_multipolygon, - Geometry::wkb_polygon)); - } - | POINT_SYM '(' expr ',' expr ')' - { - $$= GEOM_NEW(thd, Item_func_point(thd, $3, $5)); - } - | POLYGON '(' expr_list ')' - { - $$= GEOM_NEW(thd, - Item_func_spatial_collection(thd, *$3, - Geometry::wkb_polygon, - Geometry::wkb_linestring)); - } - | WITHIN '(' expr ',' expr ')' - { - $$= GEOM_NEW(thd, Item_func_spatial_precise_rel(thd, $3, $5, - Item_func::SP_WITHIN_FUNC)); - } ; /* @@ -11101,6 +11054,7 @@ function_call_generic: } opt_udf_expr_list ')' { + const Type_handler *h; Create_func *builder; Item *item= NULL; @@ -11116,8 +11070,12 @@ function_call_generic: This will be revised with WL#2128 (SQL PATH) */ - builder= find_native_function_builder(thd, &$1); - if (builder) + if ((h= Type_handler::handler_by_name($1)) && + (item= h->make_constructor_item(thd, $4))) + { + // Found a constructor with a proper argument count + } + else if ((builder= find_native_function_builder(thd, &$1))) { item= builder->create_func(thd, &$1, $4); } @@ -11148,6 +11106,18 @@ function_call_generic: if (unlikely(! ($$= item))) MYSQL_YYABORT; } + | CONTAINS_SYM '(' opt_expr_list ')' + { + if (!($$= Lex->make_item_func_call_native_or_parse_error(thd, + $1, $3))) + MYSQL_YYABORT; + } + | WITHIN '(' opt_expr_list ')' + { + if (!($$= Lex->make_item_func_call_native_or_parse_error(thd, + $1, $3))) + MYSQL_YYABORT; + } | ident_cli '.' ident_cli '(' opt_expr_list ')' { if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5)))) @@ -11204,7 +11174,7 @@ udf_expr: if ($4.str) { $2->is_autogenerated_name= FALSE; - $2->set_name(thd, $4.str, $4.length, system_charset_info); + $2->set_name(thd, $4); } /* A field has to have its proper name in order for name @@ -11750,12 +11720,20 @@ cast_type: } | cast_type_numeric { $$= $1; Lex->charset= NULL; } | cast_type_temporal { $$= $1; Lex->charset= NULL; } + | IDENT_sys + { + const Type_handler *h; + if (!(h= Type_handler::handler_by_name_or_error($1))) + MYSQL_YYABORT; + $$.set(h); + Lex->charset= NULL; + } ; cast_type_numeric: - INT_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM { $$.set(&type_handler_longlong); } - | SIGNED_SYM INT_SYM { $$.set(&type_handler_longlong); } + INT_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM { $$.set(&type_handler_slonglong); } + | SIGNED_SYM INT_SYM { $$.set(&type_handler_slonglong); } | UNSIGNED { $$.set(&type_handler_ulonglong); } | UNSIGNED INT_SYM { $$.set(&type_handler_ulonglong); } | DECIMAL_SYM float_options { $$.set(&type_handler_newdecimal, $2); } @@ -12933,7 +12911,7 @@ procedure_clause: lex->proc_list.next= &lex->proc_list.first; Item_field *item= new (thd->mem_root) Item_field(thd, &lex->current_select->context, - NULL, NULL, &$2); + $2); if (unlikely(item == NULL)) MYSQL_YYABORT; if (unlikely(add_proc_to_list(thd, item))) @@ -14172,20 +14150,26 @@ show_param: } | ALL SLAVES STATUS_SYM { + if (!(Lex->m_sql_cmd= new (thd->mem_root) + Sql_cmd_show_slave_status(true))) + MYSQL_YYABORT; Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - Lex->verbose= 1; } | SLAVE STATUS_SYM { LEX *lex= thd->lex; lex->mi.connection_name= null_clex_str; + if (!(lex->m_sql_cmd= new (thd->mem_root) + Sql_cmd_show_slave_status())) + MYSQL_YYABORT; lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - lex->verbose= 0; } | SLAVE connection_name STATUS_SYM { + if (!(Lex->m_sql_cmd= new (thd->mem_root) + Sql_cmd_show_slave_status())) + MYSQL_YYABORT; Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; - Lex->verbose= 0; } | CREATE PROCEDURE_SYM sp_name { @@ -15138,8 +15122,8 @@ literal: will include the introducer and the original hex/bin notation. */ item_str= new (thd->mem_root) - Item_string_with_introducer(thd, NULL, $2->ptr(), $2->length(), - $1); + Item_string_with_introducer(thd, null_clex_str, + $2->lex_cstring(), $1); if (unlikely(!item_str || !item_str->check_well_formed_result(true))) MYSQL_YYABORT; @@ -15539,13 +15523,9 @@ ident_table_alias: } ; -ident_set_usual_case: - IDENT_sys - | keyword_set_usual_case - { - if (unlikely($$.copy_keyword(thd, &$1))) - MYSQL_YYABORT; - } +ident_cli_set_usual_case: + IDENT_cli { $$= $1; } + | keyword_set_usual_case { $$= $1; } ; ident_sysvar_name: @@ -15886,21 +15866,13 @@ keyword_data_type: | DATETIME | ENUM | FIXED_SYM - | GEOMETRYCOLLECTION - | GEOMETRY_SYM | JSON_SYM - | LINESTRING | MEDIUM_SYM - | MULTILINESTRING - | MULTIPOINT - | MULTIPOLYGON | NATIONAL_SYM | NCHAR_SYM | NUMBER_MARIADB_SYM | NUMBER_ORACLE_SYM | NVARCHAR_SYM - | POINT_SYM - | POLYGON | RAW_MARIADB_SYM | RAW_ORACLE_SYM | ROW_SYM @@ -16255,111 +16227,78 @@ set: if (lex->main_select_push()) MYSQL_YYABORT; lex->set_stmt_init(); - lex->var_list.empty(); - sp_create_assignment_lex(thd, yychar == YYEMPTY); } - start_option_value_list + set_param { Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } - | SET STATEMENT_SYM + ; + +set_param: + option_value_no_option_type + | option_value_no_option_type ',' option_value_list + | TRANSACTION_SYM { - if (Lex->main_select_push()) + Lex->option_type= OPT_DEFAULT; + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + transaction_characteristics + { + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; - Lex->set_stmt_init(); } - set_stmt_option_value_following_option_type_list + | option_type + { + Lex->option_type= $1; + } + start_option_value_list_following_option_type + | STATEMENT_SYM + set_stmt_option_list { LEX *lex= Lex; if (unlikely(lex->table_or_sp_used())) my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT")); lex->stmt_var_list= lex->var_list; lex->var_list.empty(); - Lex->pop_select(); //main select if (Lex->check_main_unit_semantics()) MYSQL_YYABORT; } FOR_SYM verb_clause - {} ; -set_stmt_option_value_following_option_type_list: +set_stmt_option_list: /* Only system variables can be used here. If this condition is changed please check careful code under lex->option_type == OPT_STATEMENT condition on wrong type casts. */ - option_value_following_option_type - | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type - ; - -/* Start of option value list */ -start_option_value_list: - option_value_no_option_type - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - option_value_list_continued - | TRANSACTION_SYM - { - Lex->option_type= OPT_DEFAULT; - } - transaction_characteristics - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_type - { - Lex->option_type= $1; - } - start_option_value_list_following_option_type + set_stmt_option + | set_stmt_option_list ',' set_stmt_option ; - /* Start of option value list, option_type was given */ start_option_value_list_following_option_type: option_value_following_option_type + | option_value_following_option_type ',' option_value_list + | TRANSACTION_SYM { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - option_value_list_continued - | TRANSACTION_SYM transaction_characteristics + transaction_characteristics { if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } ; -/* Remainder of the option value list after first option value. */ -option_value_list_continued: - /* empty */ - | ',' option_value_list - ; - /* Repeating list of option values after first option value. */ option_value_list: - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } - | option_value_list ',' - { - sp_create_assignment_lex(thd, yychar == YYEMPTY); - } - option_value - { - if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) - MYSQL_YYABORT; - } + | option_value_list ',' option_value ; /* Wrapper around option values following the first option value in the stmt. */ @@ -16392,16 +16331,21 @@ opt_var_ident_type: | SESSION_SYM '.' { $$=OPT_SESSION; } ; -/* Option values with preceding option_type. */ -option_value_following_option_type: - ident equal set_expr_or_default +/* + SET STATEMENT options do not need their own LEX or Query_arena. + Let's put them to the main ones. +*/ +set_stmt_option: + ident_cli equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(Lex->option_type, &$1, $3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $3))) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + | ident_cli '.' ident equal set_expr_or_default { - if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $5))) MYSQL_YYABORT; } | DEFAULT '.' ident equal set_expr_or_default @@ -16411,45 +16355,132 @@ option_value_following_option_type: } ; + +/* Option values with preceding option_type. */ +option_value_following_option_type: + ident_cli equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(Lex->option_type, &tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | ident_cli '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + ; + /* Option values without preceding option_type. */ option_value_no_option_type: - ident_set_usual_case equal set_expr_or_default + ident_cli_set_usual_case equal { - if (unlikely(Lex->set_variable(&$1, $3))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | ident '.' ident equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, &$3, $5))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | DEFAULT '.' ident equal set_expr_or_default + | ident_cli_set_usual_case '.' ident equal { - if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $5))) + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; + } + set_expr_or_default + { + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, &$3, $6)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' ident_or_text equal expr + | DEFAULT '.' ident equal { - if (unlikely(Lex->set_user_variable(thd, &$2, $4))) + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_system_variable($3, &$4, $6))) + if (unlikely(Lex->set_default_system_variable(Lex->option_type, &$3, $6))) + MYSQL_YYABORT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal set_expr_or_default + | '@' ident_or_text equal { - if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $8))) + if (sp_create_assignment_lex(thd, $1.str)) MYSQL_YYABORT; } - | '@' '@' opt_var_ident_type DEFAULT '.' ident equal set_expr_or_default + expr { - if (unlikely(Lex->set_default_system_variable($3, &$6, $8))) + if (unlikely(Lex->set_user_variable(thd, &$2, $5)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_system_variable($3, &$4, $7)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | '@' '@' opt_var_ident_type DEFAULT '.' ident equal + { + if (sp_create_assignment_lex(thd, $1.str)) + MYSQL_YYABORT; + } + set_expr_or_default + { + if (unlikely(Lex->set_default_system_variable($3, &$6, $9)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= thd->lex; CHARSET_INFO *cs2; cs2= $2 ? $2: global_system_variables.character_set_client; @@ -16461,6 +16492,8 @@ option_value_no_option_type: if (unlikely(var == NULL)) MYSQL_YYABORT; lex->var_list.push_back(var, thd->mem_root); + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | NAMES_SYM equal expr { @@ -16475,6 +16508,8 @@ option_value_no_option_type: } | NAMES_SYM charset_name_or_default opt_collate { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex= Lex; CHARSET_INFO *cs2; CHARSET_INFO *cs3; @@ -16489,11 +16524,14 @@ option_value_no_option_type: set_var_collation_client *var; var= new (thd->mem_root) set_var_collation_client(cs3, cs3, cs3); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; LEX_USER *user; if (unlikely(!(user=(LEX_USER *) thd->calloc(sizeof(LEX_USER))))) @@ -16509,9 +16547,13 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | DEFAULT ROLE_SYM grant_role FOR_SYM user { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_default_role *var= (new (thd->mem_root) set_var_default_role($5, $3->user)); @@ -16521,22 +16563,36 @@ option_value_no_option_type: thd->lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } | ROLE_SYM ident_or_text { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_role *var= new (thd->mem_root) set_var_role($2); if (unlikely(var == NULL) || - unlikely(lex->var_list.push_back(var, thd->mem_root))) + unlikely(lex->var_list.push_back(var, thd->mem_root)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; + } + | ROLE_SYM equal + { + if (sp_create_assignment_lex(thd, $1.pos())) MYSQL_YYABORT; } - | ROLE_SYM equal set_expr_or_default + set_expr_or_default { - if (unlikely(Lex->set_variable(&$1, $3))) + Lex_ident_sys tmp(thd, &$1); + if (unlikely(Lex->set_variable(&tmp, $4)) || + unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) MYSQL_YYABORT; } | PASSWORD_SYM opt_for_user text_or_password { + if (sp_create_assignment_lex(thd, $1.pos())) + MYSQL_YYABORT; LEX *lex = Lex; set_var_password *var= (new (thd->mem_root) set_var_password(lex->definer)); @@ -16546,6 +16602,8 @@ option_value_no_option_type: lex->autocommit= TRUE; if (lex->sphead) lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY))) + MYSQL_YYABORT; } ; @@ -17519,10 +17577,10 @@ release: unit_type_decl: UNION_SYM union_option { $$.unit_type= UNION_TYPE; $$.distinct= $2; } - | INTERSECT_SYM - { $$.unit_type= INTERSECT_TYPE; $$.distinct= 1; } - | EXCEPT_SYM - { $$.unit_type= EXCEPT_TYPE; $$.distinct= 1; } + | INTERSECT_SYM union_option + { $$.unit_type= INTERSECT_TYPE; $$.distinct= $2; } + | EXCEPT_SYM union_option + { $$.unit_type= EXCEPT_TYPE; $$.distinct= $2; } ; /* |