diff options
author | Michael Widenius <monty@mariadb.org> | 2016-06-24 23:42:35 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-06-30 11:43:02 +0200 |
commit | fb67cde2370f7427b3279309daac712c369f1cf8 (patch) | |
tree | 94eecb3c669fdf00957f49741b75ee6eec057826 /sql/sql_yacc.yy | |
parent | 8f226121e52cbaa332964b24bd27e8babf9f2b06 (diff) | |
download | mariadb-git-fb67cde2370f7427b3279309daac712c369f1cf8.tar.gz |
Use default character set for expressions
- Force usage of () around complex DEFAULT expressions
- Give error if DEFAULT expression contains invalid characters
- Don't use const_charset_conversion for stored Item_func_sysconf expressions
as the result is not constaint over different executions
- Fixed Item_func_user() to not store calculated value in str_value
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 169 |
1 files changed, 102 insertions, 67 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 42100d6b4cf..3d0cbfb4c16 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -936,7 +936,7 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) MYSQL_YYABORT; \ } while(0) -Virtual_column_info *add_virtual_expression(THD *thd, char *txt, +Virtual_column_info *add_virtual_expression(THD *thd, const char *txt, size_t size, Item *expr) { CHARSET_INFO *cs= thd->charset(); @@ -958,6 +958,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, char *txt, v->expr_str.str= (char* ) thd->strmake(txt, size); v->expr_str.length= size; v->expr_item= expr; + v->utf8= 0; /* connection charset */ return v; } @@ -1854,9 +1855,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); simple_ident expr opt_expr opt_else sum_expr in_sum_expr variable variable_aux bool_pri predicate bit_expr - table_wild simple_expr udf_expr + table_wild simple_expr column_default_non_parenthesized_expr udf_expr expr_or_default set_expr_or_default - geometry_function + geometry_function signed_literal opt_escape sp_opt_default simple_ident_nospvar simple_ident_q @@ -1957,6 +1958,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <myvar> select_outvar %type <virtual_column> opt_check_constraint check_constraint virtual_column_func + column_default_expr %type <NONE> analyze_stmt_command @@ -2021,7 +2023,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); definer_opt no_definer definer get_diagnostics parse_vcol_expr vcol_opt_specifier vcol_opt_attribute vcol_opt_attribute_list vcol_attribute - explainable_command + explainable_command opt_impossible_action END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -6420,6 +6422,26 @@ virtual_column_func: } ; +column_default_expr: + '(' virtual_column_func ')' { $$= $2; } + | remember_name column_default_non_parenthesized_expr opt_impossible_action remember_end + { + if (!($$= add_virtual_expression(thd, $1, (uint) ($4- $1), $2))) + MYSQL_YYABORT; + } + | signed_literal + { + if (!($$= add_virtual_expression(thd, "literal", 6, $1))) + MYSQL_YYABORT; + } + ; + +/* This is to force remember_end to look at next token */ +opt_impossible_action: + IMPOSSIBLE_ACTION {} + | /* empty */ {} + + field_type: int_type opt_field_length field_options { $$.set($1, $2); } | real_type opt_precision field_options { $$.set($1, $2); } @@ -6713,7 +6735,7 @@ opt_attribute_list: attribute: NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; } | NOT_NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; } - | DEFAULT virtual_column_func { Lex->last_field->default_value= $2; } + | DEFAULT column_default_expr { Lex->last_field->default_value= $2; } | ON UPDATE_SYM NOW_SYM opt_default_time_precision { Item *item= new (thd->mem_root) Item_func_now_local(thd, $4); @@ -9490,34 +9512,17 @@ dyncall_create_list: } ; -simple_expr: +column_default_non_parenthesized_expr: simple_ident | function_call_keyword | function_call_nonkeyword | function_call_generic | function_call_conflict - | simple_expr COLLATE_SYM ident_or_text %prec NEG - { - Item *i1= new (thd->mem_root) Item_string(thd, $3.str, - $3.length, - thd->charset()); - if (i1 == NULL) - MYSQL_YYABORT; - $$= new (thd->mem_root) Item_func_set_collation(thd, $1, i1); - if ($$ == NULL) - MYSQL_YYABORT; - } | literal | param_marker { $$= $1; } | variable | sum_expr | window_func_expr - | simple_expr OR_OR_SYM simple_expr - { - $$= new (thd->mem_root) Item_func_concat(thd, $1, $3); - if ($$ == NULL) - MYSQL_YYABORT; - } | NOT_NULL_SYM { /* Replace NOT NULL with NULL */ @@ -9525,43 +9530,6 @@ simple_expr: if ($$ == NULL) MYSQL_YYABORT; } - | '+' simple_expr %prec NEG - { - $$= $2; - } - | '-' simple_expr %prec NEG - { - $$= $2->neg(thd); - if ($$ == NULL) - MYSQL_YYABORT; - } - | '~' simple_expr %prec NEG - { - $$= new (thd->mem_root) Item_func_bit_neg(thd, $2); - if ($$ == NULL) - MYSQL_YYABORT; - } - | not2 simple_expr %prec NEG - { - $$= negate_expression(thd, $2); - if ($$ == NULL) - MYSQL_YYABORT; - } - | '(' subselect ')' - { - $$= new (thd->mem_root) Item_singlerow_subselect(thd, $2); - if ($$ == NULL) - MYSQL_YYABORT; - } - | '(' expr ')' - { $$= $2; } - | '(' expr ',' expr_list ')' - { - $4->push_front($2, thd->mem_root); - $$= new (thd->mem_root) Item_row(thd, *$4); - if ($$ == NULL) - MYSQL_YYABORT; - } | ROW_SYM '(' expr ',' expr_list ')' { $5->push_front($3, thd->mem_root); @@ -9609,13 +9577,6 @@ simple_expr: Select->add_ftfunc_to_list(thd, i1); $$= i1; } - | BINARY simple_expr %prec NEG - { - $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL, - &my_charset_bin); - if ($$ == NULL) - MYSQL_YYABORT; - } | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; @@ -9664,6 +9625,71 @@ simple_expr: if ($$ == NULL) MYSQL_YYABORT; } + ; + +simple_expr: + column_default_non_parenthesized_expr + | simple_expr COLLATE_SYM ident_or_text %prec NEG + { + Item *i1= new (thd->mem_root) Item_string(thd, $3.str, + $3.length, + thd->charset()); + if (i1 == NULL) + MYSQL_YYABORT; + $$= new (thd->mem_root) Item_func_set_collation(thd, $1, i1); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '(' subselect ')' + { + $$= new (thd->mem_root) Item_singlerow_subselect(thd, $2); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '(' expr ')' + { $$= $2; } + | '(' expr ',' expr_list ')' + { + $4->push_front($2, thd->mem_root); + $$= new (thd->mem_root) Item_row(thd, *$4); + if ($$ == NULL) + MYSQL_YYABORT; + } + | BINARY simple_expr %prec NEG + { + $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL, + &my_charset_bin); + if ($$ == NULL) + MYSQL_YYABORT; + } + | simple_expr OR_OR_SYM simple_expr + { + $$= new (thd->mem_root) Item_func_concat(thd, $1, $3); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '+' simple_expr %prec NEG + { + $$= $2; + } + | '-' simple_expr %prec NEG + { + $$= $2->neg(thd); + if ($$ == NULL) + MYSQL_YYABORT; + } + | '~' simple_expr %prec NEG + { + $$= new (thd->mem_root) Item_func_bit_neg(thd, $2); + if ($$ == NULL) + MYSQL_YYABORT; + } + | not2 simple_expr %prec NEG + { + $$= negate_expression(thd, $2); + if ($$ == NULL) + MYSQL_YYABORT; + } | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM /* we cannot put interval before - */ { @@ -14035,6 +14061,15 @@ param_marker: } ; +signed_literal: + '+' NUM_literal { $$ = $2; } + | '-' NUM_literal + { + $2->max_length++; + $$= $2->neg(thd); + } + ; + literal: text_literal { $$ = $1; } | NUM_literal { $$ = $1; } |