Commit 2a13b3db authored by Alexander Barkov's avatar Alexander Barkov

MDEV-15714 Remove the use of STRING_ITEM from the parser

parent b81a403e
...@@ -4043,6 +4043,23 @@ Item *Item_null::clone_item(THD *thd) ...@@ -4043,6 +4043,23 @@ Item *Item_null::clone_item(THD *thd)
return new (thd->mem_root) Item_null(thd, name.str); return new (thd->mem_root) Item_null(thd, name.str);
} }
Item_basic_constant *
Item_null::make_string_literal_concat(THD *thd, const LEX_CSTRING *str)
{
DBUG_ASSERT(thd->variables.sql_mode & MODE_EMPTY_STRING_IS_NULL);
if (str->length)
{
CHARSET_INFO *cs= thd->variables.collation_connection;
uint repertoire= my_string_repertoire(cs, str->str, str->length);
return new (thd->mem_root) Item_string(thd,
str->str, (uint) str->length, cs,
DERIVATION_COERCIBLE, repertoire);
}
return this;
}
/*********************** Item_param related ******************************/ /*********************** Item_param related ******************************/
Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg,
...@@ -6998,6 +7015,41 @@ Item *Item_string::clone_item(THD *thd) ...@@ -6998,6 +7015,41 @@ Item *Item_string::clone_item(THD *thd)
} }
Item_basic_constant *
Item_string::make_string_literal_concat(THD *thd, const LEX_CSTRING *str)
{
append(str->str, (uint32) str->length);
if (!(collation.repertoire & MY_REPERTOIRE_EXTENDED))
{
// If the string has been pure ASCII so far, check the new part.
CHARSET_INFO *cs= thd->variables.collation_connection;
collation.repertoire|= my_string_repertoire(cs, str->str, str->length);
}
return this;
}
/*
If "this" is a reasonably short pure ASCII string literal,
try to parse known ODBC-style date, time or timestamp literals,
e.g:
SELECT {d'2001-01-01'};
SELECT {t'10:20:30'};
SELECT {ts'2001-01-01 10:20:30'};
*/
Item *Item_string::make_odbc_literal(THD *thd, const LEX_CSTRING *typestr)
{
enum_field_types type= odbc_temporal_literal_type(typestr);
Item *res= type == MYSQL_TYPE_STRING ? this :
create_temporal_literal(thd, val_str(NULL), type, false);
/*
create_temporal_literal() returns NULL if failed to parse the string,
or the string format did not match the type, e.g.: {d'2001-01-01 10:10:10'}
*/
return res ? res : this;
}
static int save_int_value_in_field (Field *field, longlong nr, static int save_int_value_in_field (Field *field, longlong nr,
bool null_value, bool unsigned_flag) bool null_value, bool unsigned_flag)
{ {
......
...@@ -1554,6 +1554,10 @@ class Item: public Value_source, ...@@ -1554,6 +1554,10 @@ class Item: public Value_source,
virtual Item *copy_andor_structure(THD *thd) { return this; } virtual Item *copy_andor_structure(THD *thd) { return this; }
virtual Item *real_item() { return this; } virtual Item *real_item() { return this; }
virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); } virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
virtual Item *make_odbc_literal(THD *thd, const LEX_CSTRING *typestr)
{
return this;
}
static CHARSET_INFO *default_charset(); static CHARSET_INFO *default_charset();
...@@ -2329,6 +2333,12 @@ class Item_basic_constant :public Item_basic_value ...@@ -2329,6 +2333,12 @@ class Item_basic_constant :public Item_basic_value
void set_used_tables(table_map map) { used_table_map= map; } void set_used_tables(table_map map) { used_table_map= map; }
table_map used_tables() const { return used_table_map; } table_map used_tables() const { return used_table_map; }
bool check_vcol_func_processor(void *arg) { return FALSE;} bool check_vcol_func_processor(void *arg) { return FALSE;}
virtual Item_basic_constant *make_string_literal_concat(THD *thd,
const LEX_CSTRING *)
{
DBUG_ASSERT(0);
return this;
}
/* to prevent drop fixed flag (no need parent cleanup call) */ /* to prevent drop fixed flag (no need parent cleanup call) */
void cleanup() void cleanup()
{ {
...@@ -3169,6 +3179,8 @@ class Item_null :public Item_basic_constant ...@@ -3169,6 +3179,8 @@ class Item_null :public Item_basic_constant
Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs); Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
bool check_partition_func_processor(void *int_arg) {return FALSE;} bool check_partition_func_processor(void *int_arg) {return FALSE;}
Item_basic_constant *make_string_literal_concat(THD *thd,
const LEX_CSTRING *);
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_null>(thd, this); } { return get_item_copy<Item_null>(thd, this); }
}; };
...@@ -3956,7 +3968,10 @@ class Item_string :public Item_basic_constant ...@@ -3956,7 +3968,10 @@ class Item_string :public Item_basic_constant
} }
return MYSQL_TYPE_STRING; // Not a temporal literal return MYSQL_TYPE_STRING; // Not a temporal literal
} }
Item_basic_constant *make_string_literal_concat(THD *thd,
const LEX_CSTRING *);
Item *make_odbc_literal(THD *thd, const LEX_CSTRING *typestr);
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
{ return get_item_copy<Item_string>(thd, this); } { return get_item_copy<Item_string>(thd, this); }
......
...@@ -2495,8 +2495,8 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs) ...@@ -2495,8 +2495,8 @@ bool THD::convert_string(String *s, CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
} }
Item *THD::make_string_literal(const char *str, size_t length, Item_basic_constant *
uint repertoire) THD::make_string_literal(const char *str, size_t length, uint repertoire)
{ {
if (!length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL)) if (!length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
return new (mem_root) Item_null(this, 0, variables.collation_connection); return new (mem_root) Item_null(this, 0, variables.collation_connection);
...@@ -2517,7 +2517,8 @@ Item *THD::make_string_literal(const char *str, size_t length, ...@@ -2517,7 +2517,8 @@ Item *THD::make_string_literal(const char *str, size_t length,
} }
Item *THD::make_string_literal_nchar(const Lex_string_with_metadata_st &str) Item_basic_constant *
THD::make_string_literal_nchar(const Lex_string_with_metadata_st &str)
{ {
DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info)); DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL)) if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
...@@ -2530,8 +2531,9 @@ Item *THD::make_string_literal_nchar(const Lex_string_with_metadata_st &str) ...@@ -2530,8 +2531,9 @@ Item *THD::make_string_literal_nchar(const Lex_string_with_metadata_st &str)
} }
Item *THD::make_string_literal_charset(const Lex_string_with_metadata_st &str, Item_basic_constant *
CHARSET_INFO *cs) THD::make_string_literal_charset(const Lex_string_with_metadata_st &str,
CHARSET_INFO *cs)
{ {
if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL)) if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
return new (mem_root) Item_null(this, 0, cs); return new (mem_root) Item_null(this, 0, cs);
...@@ -2540,34 +2542,6 @@ Item *THD::make_string_literal_charset(const Lex_string_with_metadata_st &str, ...@@ -2540,34 +2542,6 @@ Item *THD::make_string_literal_charset(const Lex_string_with_metadata_st &str,
} }
Item *THD::make_string_literal_concat(Item *item, const LEX_CSTRING &str)
{
if (item->type() == Item::NULL_ITEM)
{
DBUG_ASSERT(variables.sql_mode & MODE_EMPTY_STRING_IS_NULL);
if (str.length)
{
CHARSET_INFO *cs= variables.collation_connection;
uint repertoire= my_string_repertoire(cs, str.str, str.length);
return new (mem_root) Item_string(this, str.str, (uint)str.length, cs,
DERIVATION_COERCIBLE, repertoire);
}
return item;
}
DBUG_ASSERT(item->type() == Item::STRING_ITEM);
DBUG_ASSERT(item->basic_const_item());
static_cast<Item_string*>(item)->append(str.str, (uint)str.length);
if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
{
// If the string has been pure ASCII so far, check the new part.
CHARSET_INFO *cs= variables.collation_connection;
item->collation.repertoire|= my_string_repertoire(cs, str.str, str.length);
}
return item;
}
/* /*
Update some cache variables when character set changes Update some cache variables when character set changes
*/ */
......
...@@ -3721,17 +3721,16 @@ class THD :public Statement, ...@@ -3721,17 +3721,16 @@ class THD :public Statement,
@param length - length of the string @param length - length of the string
@param repertoire - the repertoire of the string @param repertoire - the repertoire of the string
*/ */
Item *make_string_literal(const char *str, size_t length, Item_basic_constant *make_string_literal(const char *str, size_t length,
uint repertoire); uint repertoire);
Item *make_string_literal(const Lex_string_with_metadata_st &str) Item_basic_constant *make_string_literal(const Lex_string_with_metadata_st &str)
{ {
uint repertoire= str.repertoire(variables.character_set_client); uint repertoire= str.repertoire(variables.character_set_client);
return make_string_literal(str.str, str.length, repertoire); return make_string_literal(str.str, str.length, repertoire);
} }
Item *make_string_literal_nchar(const Lex_string_with_metadata_st &str); Item_basic_constant *make_string_literal_nchar(const Lex_string_with_metadata_st &str);
Item *make_string_literal_charset(const Lex_string_with_metadata_st &str, Item_basic_constant *make_string_literal_charset(const Lex_string_with_metadata_st &str,
CHARSET_INFO *cs); CHARSET_INFO *cs);
Item *make_string_literal_concat(Item *item1, const LEX_CSTRING &str);
void add_changed_table(TABLE *table); void add_changed_table(TABLE *table);
void add_changed_table(const char *key, size_t key_length); void add_changed_table(const char *key, size_t key_length);
CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length); CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length);
......
...@@ -807,6 +807,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) ...@@ -807,6 +807,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
Item *item; Item *item;
Item_num *item_num; Item_num *item_num;
Item_param *item_param; Item_param *item_param;
Item_basic_constant *item_basic_constant;
Key_part_spec *key_part; Key_part_spec *key_part;
LEX *lex; LEX *lex;
sp_assignment_lex *assignment_lex; sp_assignment_lex *assignment_lex;
...@@ -1760,7 +1761,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1760,7 +1761,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
replace_lock_option opt_low_priority insert_lock_option load_data_lock replace_lock_option opt_low_priority insert_lock_option load_data_lock
%type <item> %type <item>
literal text_literal insert_ident order_ident temporal_literal literal insert_ident order_ident temporal_literal
simple_ident expr sum_expr in_sum_expr simple_ident expr sum_expr in_sum_expr
variable variable_aux bool_pri variable variable_aux bool_pri
predicate bit_expr parenthesized_expr predicate bit_expr parenthesized_expr
...@@ -1792,6 +1793,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1792,6 +1793,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <item_num> %type <item_num>
NUM_literal NUM_literal
%type <item_basic_constant> text_literal
%type <item_list> %type <item_list>
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
ident_list ident_list_arg opt_expr_list ident_list ident_list_arg opt_expr_list
...@@ -9948,27 +9951,8 @@ column_default_non_parenthesized_expr: ...@@ -9948,27 +9951,8 @@ column_default_non_parenthesized_expr:
} }
| '{' ident expr '}' | '{' ident expr '}'
{ {
$$= NULL; if (!($$= $3->make_odbc_literal(thd, &$2)))
/* MYSQL_YYABORT;
If "expr" is reasonably short pure ASCII string literal,
try to parse known ODBC style date, time or timestamp literals,
e.g:
SELECT {d'2001-01-01'};
SELECT {t'10:20:30'};
SELECT {ts'2001-01-01 10:20:30'};
*/
if ($3->type() == Item::STRING_ITEM)
{
Item_string *item= (Item_string *) $3;
enum_field_types type= item->odbc_temporal_literal_type(&$2);
if (type != MYSQL_TYPE_STRING)
{
$$= create_temporal_literal(thd, item->val_str(NULL),
type, false);
}
}
if ($$ == NULL)
$$= $3;
} }
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{ {
...@@ -14682,7 +14666,7 @@ text_literal: ...@@ -14682,7 +14666,7 @@ text_literal:
} }
| text_literal TEXT_STRING_literal | text_literal TEXT_STRING_literal
{ {
if (!($$= thd->make_string_literal_concat($1, $2))) if (!($$= $1->make_string_literal_concat(thd, &$2)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
; ;
......
...@@ -198,6 +198,7 @@ void ORAerror(THD *thd, const char *s) ...@@ -198,6 +198,7 @@ void ORAerror(THD *thd, const char *s)
Item *item; Item *item;
Item_num *item_num; Item_num *item_num;
Item_param *item_param; Item_param *item_param;
Item_basic_constant *item_basic_constant;
Key_part_spec *key_part; Key_part_spec *key_part;
LEX *lex; LEX *lex;
sp_assignment_lex *assignment_lex; sp_assignment_lex *assignment_lex;
...@@ -1156,7 +1157,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1156,7 +1157,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
replace_lock_option opt_low_priority insert_lock_option load_data_lock replace_lock_option opt_low_priority insert_lock_option load_data_lock
%type <item> %type <item>
literal text_literal insert_ident order_ident temporal_literal literal insert_ident order_ident temporal_literal
simple_ident expr sum_expr in_sum_expr simple_ident expr sum_expr in_sum_expr
variable variable_aux bool_pri variable variable_aux bool_pri
predicate bit_expr parenthesized_expr predicate bit_expr parenthesized_expr
...@@ -1189,6 +1190,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); ...@@ -1189,6 +1190,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <item_num> %type <item_num>
NUM_literal NUM_literal
%type <item_basic_constant> text_literal
%type <item_list> %type <item_list>
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
ident_list ident_list_arg opt_expr_list ident_list ident_list_arg opt_expr_list
...@@ -9727,27 +9730,8 @@ column_default_non_parenthesized_expr: ...@@ -9727,27 +9730,8 @@ column_default_non_parenthesized_expr:
} }
| '{' ident expr '}' | '{' ident expr '}'
{ {
$$= NULL; if (!($$= $3->make_odbc_literal(thd, &$2)))
/* MYSQL_YYABORT;
If "expr" is reasonably short pure ASCII string literal,
try to parse known ODBC style date, time or timestamp literals,
e.g:
SELECT {d'2001-01-01'};
SELECT {t'10:20:30'};
SELECT {ts'2001-01-01 10:20:30'};
*/
if ($3->type() == Item::STRING_ITEM)
{
Item_string *item= (Item_string *) $3;
enum_field_types type= item->odbc_temporal_literal_type(&$2);
if (type != MYSQL_TYPE_STRING)
{
$$= create_temporal_literal(thd, item->val_str(NULL),
type, false);
}
}
if ($$ == NULL)
$$= $3;
} }
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{ {
...@@ -14404,7 +14388,7 @@ text_literal: ...@@ -14404,7 +14388,7 @@ text_literal:
} }
| text_literal TEXT_STRING_literal | text_literal TEXT_STRING_literal
{ {
if (!($$= thd->make_string_literal_concat($1, $2))) if (!($$= $1->make_string_literal_concat(thd, &$2)))
MYSQL_YYABORT; MYSQL_YYABORT;
} }
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment