diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-11-23 18:55:01 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-11-23 18:55:01 +0400 |
commit | d73cf394a5361b33baf40afd2a8c1d4edac548c0 (patch) | |
tree | 320158af832dc8e74320ff308c3c51eb5549cbfa | |
parent | b7e9bf91221663ca70f87d59846ecad848b5c786 (diff) | |
download | mariadb-git-d73cf394a5361b33baf40afd2a8c1d4edac548c0.tar.gz |
MDEV-9170 Get rid of LEX::length and LEX::dec
A preparatory task for:
MDEV-4912 Add a plugin to field types (column types)
-rw-r--r-- | sql/item_func.h | 27 | ||||
-rw-r--r-- | sql/sql_lex.cc | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 389 | ||||
-rw-r--r-- | sql/structs.h | 70 |
5 files changed, 252 insertions, 238 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index 6230550067b..9cf42fd5a78 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -2039,6 +2039,33 @@ enum Cast_target }; +struct Lex_cast_type_st: public Lex_length_and_dec_st +{ +private: + Cast_target m_type; +public: + void set(Cast_target type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } + void set(Cast_target type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(Cast_target type, const char *length) + { + set(type, length, 0); + } + void set(Cast_target type) + { + set(type, 0, 0); + } + Cast_target type() const { return m_type; } +}; + + class Item_func_row_count :public Item_int_func { public: diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 898e3ae33c6..f0bc582985b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -506,7 +506,6 @@ void lex_start(THD *thd) lex->parsing_options.reset(); lex->empty_field_list_on_rset= 0; lex->select_lex.select_number= 1; - lex->length=0; lex->part_info= 0; lex->select_lex.in_sum_expr=0; lex->select_lex.ftfunc_list_alloc.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 644d1a19cfd..4f3bba8c10a 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2396,7 +2396,6 @@ struct LEX: public Query_tables_list Explain_query *explain; // type information - char *length,*dec; CHARSET_INFO *charset; LEX_STRING name; @@ -2856,7 +2855,7 @@ public: void restore_set_statement_var(); void init_last_field(Create_field *field, const char *name, CHARSET_INFO *cs); - void set_last_field_type(enum enum_field_types type); + void set_last_field_type(const Lex_field_type_st &type); bool set_bincmp(CHARSET_INFO *cs, bool bin); // Check if "KEY IF NOT EXISTS name" used outside of ALTER context bool check_add_key(DDL_options_st ddl) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3656abc2d7c..72559b30a68 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -861,28 +861,26 @@ void LEX::init_last_field(Create_field *field, const char *field_name, field->field_name= field_name; /* reset LEX fields that are used in Create_field::set_and_check() */ - length= 0; - dec= 0; charset= cs; } -void LEX::set_last_field_type(enum enum_field_types field_type) +void LEX::set_last_field_type(const Lex_field_type_st &type) { - last_field->sql_type= field_type; + last_field->sql_type= type.field_type(); last_field->create_if_not_exists= check_exists; last_field->charset= charset; - if (length) + if (type.length()) { int err; - last_field->length= my_strtoll10(length, NULL, &err); + last_field->length= my_strtoll10(type.length(), NULL, &err); if (err) last_field->length= ~0ULL; // safety } else last_field->length= 0; - last_field->decimals= dec ? (uint)atoi(dec) : 0; + last_field->decimals= type.dec() ? (uint)atoi(type.dec()) : 0; } bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) @@ -924,6 +922,10 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) LEX_SYMBOL symbol; struct sys_var_with_base variable; struct { int vars, conds, hndlrs, curs; } spblock; + Lex_length_and_dec_st Lex_length_and_dec; + Lex_cast_type_st Lex_cast_type; + Lex_field_type_st Lex_field_type; + Lex_dyncol_type_st Lex_dyncol_type; /* pointers */ CHARSET_INFO *charset; @@ -960,7 +962,6 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) udf_func *udf; /* enums */ - enum Cast_target cast_type; 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; @@ -1701,11 +1702,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <simple_string> remember_name remember_end opt_db remember_tok_start wild_and_where + field_length opt_field_length opt_field_length_default_1 %type <string> text_string hex_or_bin_String opt_gconcat_separator -%type <field_type> type_with_opt_collate int_type real_type field_type +%type <field_type> int_type real_type + +%type <Lex_field_type> type_with_opt_collate field_type + +%type <Lex_dyncol_type> opt_dyncol_type dyncol_type + numeric_dyncol_type temporal_dyncol_type string_dyncol_type %type <geom_type> spatial_type @@ -1719,7 +1726,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt - optional_flush_tables_arguments opt_dyncol_type dyncol_type + optional_flush_tables_arguments opt_time_precision kill_type kill_option int_num opt_default_time_precision case_stmt_body opt_bin_mod @@ -1823,7 +1830,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <ha_rkey_mode> handler_rkey_mode -%type <cast_type> cast_type +%type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal + +%type <Lex_length_and_dec> precision opt_precision float_options %type <symbol> keyword keyword_sp @@ -1877,7 +1886,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item field_def handler opt_generated_always - opt_precision opt_ignore opt_column opt_restrict + opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use @@ -1896,9 +1905,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union_clause union_list - precision subselect_start opt_and charset + subselect_start opt_and charset subselect_end select_var_list select_var_list_init help - field_length opt_field_length opt_extended_describe shutdown opt_format_json prepare prepare_src execute deallocate @@ -2929,8 +2937,8 @@ sp_param_name_and_type: LEX *lex= Lex; sp_variable *spvar= $<spvar>2; - spvar->type= $3; - if (lex->sphead->fill_field_definition(thd, lex, $3, + spvar->type= $3.field_type(); + if (lex->sphead->fill_field_definition(thd, lex, $3.field_type(), lex->last_field)) { MYSQL_YYABORT; @@ -3026,7 +3034,7 @@ sp_decl: LEX *lex= Lex; sp_pcontext *pctx= lex->spcont; uint num_vars= pctx->context_var_count(); - enum enum_field_types var_type= $4; + enum enum_field_types var_type= $4.field_type(); Item *dflt_value_item= $5; if (!dflt_value_item) @@ -6229,15 +6237,15 @@ virtual_column_func: ; field_type: - int_type opt_field_length field_options { $$=$1; } - | real_type opt_precision field_options { $$=$1; } + 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 { - $$=MYSQL_TYPE_FLOAT; - if (Lex->length && !Lex->dec) + $$.set(MYSQL_TYPE_FLOAT, $2); + if ($2.length() && !$2.dec()) { int err; - ulonglong tmp_length= my_strtoll10(Lex->length, NULL, &err); + ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); if (err || tmp_length > PRECISION_FOR_DOUBLE) { my_error(ER_WRONG_FIELD_SPEC, MYF(0), @@ -6245,80 +6253,57 @@ field_type: MYSQL_YYABORT; } else if (tmp_length > PRECISION_FOR_FLOAT) - $$= MYSQL_TYPE_DOUBLE; - Lex->length= 0; + $$.set(MYSQL_TYPE_DOUBLE); + else + $$.set(MYSQL_TYPE_FLOAT); } } - | BIT_SYM - { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_BIT; - } - | BIT_SYM field_length + | BIT_SYM opt_field_length_default_1 { - $$=MYSQL_TYPE_BIT; + $$.set(MYSQL_TYPE_BIT, $2); } | BOOL_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; + $$.set(MYSQL_TYPE_TINY, "1"); } | BOOLEAN_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; - } - | char field_length opt_binary - { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_TINY, "1"); } - | char opt_binary + | char opt_field_length_default_1 opt_binary { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } - | nchar field_length opt_bin_mod + | nchar opt_field_length_default_1 opt_bin_mod { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); bincmp_collation(national_charset_info, $3); } - | nchar opt_bin_mod - { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; - bincmp_collation(national_charset_info, $2); - } - | BINARY field_length + | BINARY opt_field_length_default_1 { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; - } - | BINARY - { - Lex->length= (char*) "1"; - Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } | varchar field_length opt_binary { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | nvarchar field_length opt_bin_mod { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); bincmp_collation(national_charset_info, $3); } | VARBINARY field_length { Lex->charset=&my_charset_bin; - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | YEAR_SYM opt_field_length field_options { - if (Lex->length) + if ($2) { errno= 0; - ulong length= strtoul(Lex->length, NULL, 10); + ulong length= strtoul($2, NULL, 10); if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4) { char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; @@ -6329,18 +6314,18 @@ field_type: buff, "YEAR(4)"); } } - $$=MYSQL_TYPE_YEAR; + $$.set(MYSQL_TYPE_YEAR, $2); } | DATE_SYM - { $$=MYSQL_TYPE_DATE; } + { $$.set(MYSQL_TYPE_DATE); } | TIME_SYM opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); } | TIMESTAMP opt_field_length { if (thd->variables.sql_mode & MODE_MAXDB) - $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; + $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); else { /* @@ -6349,29 +6334,29 @@ field_type: */ if (!opt_explicit_defaults_for_timestamp) Lex->last_field->flags|= NOT_NULL_FLAG; - $$= opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 - : MYSQL_TYPE_TIMESTAMP; + $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 + : MYSQL_TYPE_TIMESTAMP, $2); } } | DATETIME opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); } | TINYBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_TINY_BLOB; + $$.set(MYSQL_TYPE_TINY_BLOB); } | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_BLOB; + $$.set(MYSQL_TYPE_BLOB, $2); } | spatial_type float_options srid_option { #ifdef HAVE_SPATIAL Lex->charset=&my_charset_bin; Lex->last_field->geom_type= $1; - $$=MYSQL_TYPE_GEOMETRY; + $$.set(MYSQL_TYPE_GEOMETRY, $2); #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); @@ -6381,43 +6366,43 @@ field_type: | MEDIUMBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_LONG_BLOB; + $$.set(MYSQL_TYPE_LONG_BLOB); } | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONG_SYM varchar opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | TINYTEXT opt_binary - { $$=MYSQL_TYPE_TINY_BLOB; } + { $$.set(MYSQL_TYPE_TINY_BLOB); } | TEXT_SYM opt_field_length opt_binary - { $$=MYSQL_TYPE_BLOB; } + { $$.set(MYSQL_TYPE_BLOB, $2); } | MEDIUMTEXT opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGTEXT opt_binary - { $$=MYSQL_TYPE_LONG_BLOB; } + { $$.set(MYSQL_TYPE_LONG_BLOB); } | DECIMAL_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | NUMERIC_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | FIXED_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | ENUM '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_ENUM; } + { $$.set(MYSQL_TYPE_ENUM); } | SET '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_SET; } + { $$.set(MYSQL_TYPE_SET); } | LONG_SYM opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | SERIAL_SYM { - $$=MYSQL_TYPE_LONGLONG; + $$.set(MYSQL_TYPE_LONGLONG); Lex->last_field->flags|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_FLAG); } @@ -6426,12 +6411,7 @@ field_type: spatial_type: GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } - | POINT_SYM - { - Lex->length= const_cast<char*>(STRINGIFY_ARG - (MAX_LEN_GEOM_POINT_FIELD)); - $$= Field::GEOM_POINT; - } + | POINT_SYM { $$= Field::GEOM_POINT; } | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } | LINESTRING { $$= Field::GEOM_LINESTRING; } | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } @@ -6492,21 +6472,13 @@ srid_option: ; float_options: - /* empty */ - { Lex->dec=Lex->length= (char*)0; } - | field_length - { Lex->dec= (char*)0; } - | precision - {} + /* empty */ { $$.set(0, 0); } + | field_length { $$.set($1, 0); } + | precision { $$= $1; } ; precision: - '(' NUM ',' NUM ')' - { - LEX *lex=Lex; - lex->length=$2.str; - lex->dec=$4.str; - } + '(' NUM ',' NUM ')' { $$.set($2.str, $4.str); } ; field_options: @@ -6526,19 +6498,22 @@ field_option: ; field_length: - '(' LONG_NUM ')' { Lex->length= $2.str; } - | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; } - | '(' DECIMAL_NUM ')' { Lex->length= $2.str; } - | '(' NUM ')' { Lex->length= $2.str; }; + '(' LONG_NUM ')' { $$= $2.str; } + | '(' ULONGLONG_NUM ')' { $$= $2.str; } + | '(' DECIMAL_NUM ')' { $$= $2.str; } + | '(' NUM ')' { $$= $2.str; }; opt_field_length: - /* empty */ { Lex->length=(char*) 0; /* use default length */ } - | field_length { } - ; + /* empty */ { $$= (char*) 0; /* use default length */ } + | field_length { $$= $1; } + +opt_field_length_default_1: + /* empty */ { $$= (char*) "1"; } + | field_length { $$= $1; } opt_precision: - /* empty */ {} - | precision {} + /* empty */ { $$.set(0, 0); } + | precision { $$= $1; } ; opt_attribute: @@ -9139,92 +9114,44 @@ all_or_any: opt_dyncol_type: /* empty */ { - LEX *lex= Lex; - $$= DYN_COL_NULL; /* automatic type */ - lex->charset= NULL; - lex->length= lex->dec= 0; + $$.set(DYN_COL_NULL); /* automatic type */ + Lex->charset= NULL; } | AS dyncol_type { $$= $2; } ; dyncol_type: - INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_INT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | UNSIGNED INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_UINT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DOUBLE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | REAL - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | FLOAT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DECIMAL_SYM float_options - { - $$= DYN_COL_DECIMAL; - Lex->charset= NULL; - } - | char + numeric_dyncol_type { $$= $1; Lex->charset= NULL; } + | temporal_dyncol_type { $$= $1; Lex->charset= NULL; } + | string_dyncol_type { $$= $1; } + ; + +numeric_dyncol_type: + INT_SYM { $$.set(DYN_COL_INT); } + | UNSIGNED INT_SYM { $$.set(DYN_COL_UINT); } + | DOUBLE_SYM { $$.set(DYN_COL_DOUBLE); } + | REAL { $$.set(DYN_COL_DOUBLE); } + | FLOAT_SYM { $$.set(DYN_COL_DOUBLE); } + | DECIMAL_SYM float_options { $$.set(DYN_COL_DECIMAL, $2); } + ; + +temporal_dyncol_type: + DATE_SYM { $$.set(DYN_COL_DATE); } + | TIME_SYM opt_field_length { $$.set(DYN_COL_TIME, 0, $2); } + | DATETIME opt_field_length { $$.set(DYN_COL_DATETIME, 0, $2); } + ; + +string_dyncol_type: + char { Lex->charset= thd->variables.collation_connection; } opt_binary { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->length= lex->dec= 0; + $$.set(DYN_COL_STRING); } | nchar { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->charset= national_charset_info; - lex->length= lex->dec= 0; - } - | DATE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DATE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | TIME_SYM opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_TIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; - } - | DATETIME opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_DATETIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; + $$.set(DYN_COL_STRING); + Lex->charset= national_charset_info; } ; @@ -9238,14 +9165,14 @@ dyncall_create_element: MYSQL_YYABORT; $$->key= $1; $$->value= $3; - $$->type= (DYNAMIC_COLUMN_TYPE)$4; + $$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type(); $$->cs= lex->charset; - if (lex->length) - $$->len= strtoul(lex->length, NULL, 10); + if ($4.length()) + $$->len= strtoul($4.length(), NULL, 10); else $$->len= 0; - if (lex->dec) - $$->frac= strtoul(lex->dec, NULL, 10); + if ($4.dec()) + $$->frac= strtoul($4.dec(), NULL, 10); else $$->len= 0; } @@ -9386,7 +9313,7 @@ simple_expr: | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_cast(thd, $3, $5, lex->length, lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9399,7 +9326,7 @@ simple_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), Lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9839,8 +9766,8 @@ function_call_nonkeyword: COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_dyncol_get(thd, $3, $5, $7, - lex->length, lex->dec, + $$= create_func_dyncol_get(thd, $3, $5, $7.type(), + $7.length(), $7.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -10529,43 +10456,35 @@ in_sum_expr: cast_type: BINARY opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); Lex->charset= &my_charset_bin; } | CHAR_SYM opt_field_length { Lex->charset= thd->variables.collation_connection; } opt_binary - { $$=ITEM_CAST_CHAR; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); } | NCHAR_SYM opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } - | INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED INT_SYM - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | DATE_SYM - { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | TIME_SYM opt_field_length - { - $$=ITEM_CAST_TIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DATETIME opt_field_length { - $$=ITEM_CAST_DATETIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DECIMAL_SYM float_options - { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; } - | DOUBLE_SYM - { Lex->charset= NULL; Lex->length= Lex->dec= 0;} - opt_precision - { $$=ITEM_CAST_DOUBLE; } + Lex->charset= national_charset_info; + $$.set(ITEM_CAST_CHAR, $2, 0); + } + | cast_type_numeric { $$= $1; Lex->charset= NULL; } + | cast_type_temporal { $$= $1; Lex->charset= NULL; } + ; + +cast_type_numeric: + INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | SIGNED_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | SIGNED_SYM INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } + | UNSIGNED { $$.set(ITEM_CAST_UNSIGNED_INT); } + | UNSIGNED INT_SYM { $$.set(ITEM_CAST_UNSIGNED_INT); } + | DECIMAL_SYM float_options { $$.set(ITEM_CAST_DECIMAL, $2); } + | DOUBLE_SYM opt_precision { $$.set(ITEM_CAST_DOUBLE, $2); } + ; + +cast_type_temporal: + DATE_SYM { $$.set(ITEM_CAST_DATE); } + | TIME_SYM opt_field_length { $$.set(ITEM_CAST_TIME, 0, $2); } + | DATETIME opt_field_length { $$.set(ITEM_CAST_DATETIME, 0, $2); } + ; opt_expr_list: /* empty */ { $$= NULL; } @@ -16408,7 +16327,7 @@ sf_tail: } type_with_opt_collate /* $11 */ { /* $12 */ - if (Lex->sphead->fill_field_definition(thd, Lex, $11, + if (Lex->sphead->fill_field_definition(thd, Lex, $11.field_type(), Lex->last_field)) MYSQL_YYABORT; } diff --git a/sql/structs.h b/sql/structs.h index 191463af344..8dc6323bde0 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -550,4 +550,74 @@ public: }; +struct Lex_length_and_dec_st +{ +private: + const char *m_length; + const char *m_dec; +public: + void set(const char *length, const char *dec) + { + m_length= length; + m_dec= dec; + } + const char *length() const { return m_length; } + const char *dec() const { return m_dec; } +}; + + +struct Lex_field_type_st: public Lex_length_and_dec_st +{ +private: + enum_field_types m_type; + void set(enum_field_types type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } +public: + void set(enum_field_types type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(enum_field_types type, const char *length) + { + set(type, length, 0); + } + void set(enum_field_types type) + { + set(type, 0, 0); + } + enum_field_types field_type() const { return m_type; } +}; + + +struct Lex_dyncol_type_st: public Lex_length_and_dec_st +{ +private: + int m_type; // enum_dynamic_column_type is not visible here, so use int +public: + void set(int type, const char *length, const char *dec) + { + m_type= type; + Lex_length_and_dec_st::set(length, dec); + } + void set(int type, Lex_length_and_dec_st length_and_dec) + { + m_type= type; + Lex_length_and_dec_st::operator=(length_and_dec); + } + void set(int type, const char *length) + { + set(type, length, 0); + } + void set(int type) + { + set(type, 0, 0); + } + int dyncol_type() const { return m_type; } +}; + + #endif /* STRUCTS_INCLUDED */ |