Skip to content

Commit

Permalink
MDEV-15714 Remove the use of STRING_ITEM from the parser
Browse files Browse the repository at this point in the history
  • Loading branch information
abarkov committed Mar 29, 2018
1 parent b81a403 commit 2a13b3d
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 87 deletions.
52 changes: 52 additions & 0 deletions sql/item.cc
Expand Up @@ -4043,6 +4043,23 @@ Item *Item_null::clone_item(THD *thd)
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::Item_param(THD *thd, const LEX_CSTRING *name_arg,
Expand Down Expand Up @@ -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,
bool null_value, bool unsigned_flag)
{
Expand Down
17 changes: 16 additions & 1 deletion sql/item.h
Expand Up @@ -1554,6 +1554,10 @@ class Item: public Value_source,
virtual Item *copy_andor_structure(THD *thd) { return this; }
virtual Item *real_item() { return this; }
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();

Expand Down Expand Up @@ -2329,6 +2333,12 @@ class Item_basic_constant :public Item_basic_value
void set_used_tables(table_map map) { used_table_map= map; }
table_map used_tables() const { return used_table_map; }
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) */
void cleanup()
{
Expand Down Expand Up @@ -3169,6 +3179,8 @@ class Item_null :public Item_basic_constant

Item *safe_charset_converter(THD *thd, CHARSET_INFO *tocs);
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)
{ return get_item_copy<Item_null>(thd, this); }
};
Expand Down Expand Up @@ -3956,7 +3968,10 @@ class Item_string :public Item_basic_constant
}
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)
{ return get_item_copy<Item_string>(thd, this); }

Expand Down
40 changes: 7 additions & 33 deletions sql/sql_class.cc
Expand Up @@ -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,
uint repertoire)
Item_basic_constant *
THD::make_string_literal(const char *str, size_t length, uint repertoire)
{
if (!length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
return new (mem_root) Item_null(this, 0, variables.collation_connection);
Expand All @@ -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));
if (!str.length && (variables.sql_mode & MODE_EMPTY_STRING_IS_NULL))
Expand All @@ -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,
CHARSET_INFO *cs)
Item_basic_constant *
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))
return new (mem_root) Item_null(this, 0, cs);
Expand All @@ -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
*/
Expand Down
13 changes: 6 additions & 7 deletions sql/sql_class.h
Expand Up @@ -3721,17 +3721,16 @@ class THD :public Statement,
@param length - length of the string
@param repertoire - the repertoire of the string
*/
Item *make_string_literal(const char *str, size_t length,
uint repertoire);
Item *make_string_literal(const Lex_string_with_metadata_st &str)
Item_basic_constant *make_string_literal(const char *str, size_t length,
uint repertoire);
Item_basic_constant *make_string_literal(const Lex_string_with_metadata_st &str)
{
uint repertoire= str.repertoire(variables.character_set_client);
return make_string_literal(str.str, str.length, repertoire);
}
Item *make_string_literal_nchar(const Lex_string_with_metadata_st &str);
Item *make_string_literal_charset(const Lex_string_with_metadata_st &str,
CHARSET_INFO *cs);
Item *make_string_literal_concat(Item *item1, const LEX_CSTRING &str);
Item_basic_constant *make_string_literal_nchar(const Lex_string_with_metadata_st &str);
Item_basic_constant *make_string_literal_charset(const Lex_string_with_metadata_st &str,
CHARSET_INFO *cs);
void add_changed_table(TABLE *table);
void add_changed_table(const char *key, size_t key_length);
CHANGED_TABLE_LIST * changed_table_dup(const char *key, size_t key_length);
Expand Down
30 changes: 7 additions & 23 deletions sql/sql_yacc.yy
Expand Up @@ -807,6 +807,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
Item *item;
Item_num *item_num;
Item_param *item_param;
Item_basic_constant *item_basic_constant;
Key_part_spec *key_part;
LEX *lex;
sp_assignment_lex *assignment_lex;
Expand Down Expand Up @@ -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

%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
variable variable_aux bool_pri
predicate bit_expr parenthesized_expr
Expand Down Expand Up @@ -1792,6 +1793,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <item_num>
NUM_literal

%type <item_basic_constant> text_literal

%type <item_list>
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
ident_list ident_list_arg opt_expr_list
Expand Down Expand Up @@ -9948,27 +9951,8 @@ column_default_non_parenthesized_expr:
}
| '{' ident expr '}'
{
$$= NULL;
/*
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;
if (!($$= $3->make_odbc_literal(thd, &$2)))
MYSQL_YYABORT;
}
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{
Expand Down Expand Up @@ -14682,7 +14666,7 @@ text_literal:
}
| text_literal TEXT_STRING_literal
{
if (!($$= thd->make_string_literal_concat($1, $2)))
if (!($$= $1->make_string_literal_concat(thd, &$2)))
MYSQL_YYABORT;
}
;
Expand Down
30 changes: 7 additions & 23 deletions sql/sql_yacc_ora.yy
Expand Up @@ -198,6 +198,7 @@ void ORAerror(THD *thd, const char *s)
Item *item;
Item_num *item_num;
Item_param *item_param;
Item_basic_constant *item_basic_constant;
Key_part_spec *key_part;
LEX *lex;
sp_assignment_lex *assignment_lex;
Expand Down Expand Up @@ -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

%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
variable variable_aux bool_pri
predicate bit_expr parenthesized_expr
Expand Down Expand Up @@ -1189,6 +1190,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%type <item_num>
NUM_literal

%type <item_basic_constant> text_literal

%type <item_list>
expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
ident_list ident_list_arg opt_expr_list
Expand Down Expand Up @@ -9727,27 +9730,8 @@ column_default_non_parenthesized_expr:
}
| '{' ident expr '}'
{
$$= NULL;
/*
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;
if (!($$= $3->make_odbc_literal(thd, &$2)))
MYSQL_YYABORT;
}
| MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
{
Expand Down Expand Up @@ -14404,7 +14388,7 @@ text_literal:
}
| text_literal TEXT_STRING_literal
{
if (!($$= thd->make_string_literal_concat($1, $2)))
if (!($$= $1->make_string_literal_concat(thd, &$2)))
MYSQL_YYABORT;
}
;
Expand Down

0 comments on commit 2a13b3d

Please sign in to comment.