summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-11-23 18:55:01 +0400
committerAlexander Barkov <bar@mariadb.org>2015-11-23 18:55:01 +0400
commitd73cf394a5361b33baf40afd2a8c1d4edac548c0 (patch)
tree320158af832dc8e74320ff308c3c51eb5549cbfa
parentb7e9bf91221663ca70f87d59846ecad848b5c786 (diff)
downloadmariadb-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.h27
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_yacc.yy389
-rw-r--r--sql/structs.h70
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 */