Skip to content

Commit b424420

Browse files
author
Alexander Barkov
committed
MDEV-9316 Add Field::store_hex_hybrid()
1 parent 12b86be commit b424420

File tree

4 files changed

+55
-46
lines changed

4 files changed

+55
-46
lines changed

sql/field.cc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,6 +1322,31 @@ bool Field::can_optimize_range(const Item_bool_func *cond,
13221322
}
13231323

13241324

1325+
int Field::store_hex_hybrid(const char *str, uint length)
1326+
{
1327+
DBUG_ASSERT(result_type() != STRING_RESULT);
1328+
ulonglong nr;
1329+
1330+
if (length > 8)
1331+
{
1332+
nr= flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
1333+
goto warn;
1334+
}
1335+
nr= (ulonglong) longlong_from_hex_hybrid(str, length);
1336+
if ((length == 8) && !(flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX))
1337+
{
1338+
nr= LONGLONG_MAX;
1339+
goto warn;
1340+
}
1341+
return store((longlong) nr, true); // Assume hex numbers are unsigned
1342+
1343+
warn:
1344+
if (!store((longlong) nr, true))
1345+
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
1346+
return 1;
1347+
}
1348+
1349+
13251350
/**
13261351
Numeric fields base class constructor.
13271352
*/

sql/field.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,16 @@ class Value_source
280280
return decimal_value;
281281
}
282282

283+
longlong longlong_from_hex_hybrid(const char *str, uint32 length)
284+
{
285+
const char *end= str + length;
286+
const char *ptr= end - MY_MIN(length, sizeof(longlong));
287+
ulonglong value= 0;
288+
for ( ; ptr != end ; ptr++)
289+
value= (value << 8) + (ulonglong) (uchar) *ptr;
290+
return (longlong) value;
291+
}
292+
283293
longlong longlong_from_string_with_check(const String *str) const
284294
{
285295
return longlong_from_string_with_check(str->charset(),
@@ -720,6 +730,7 @@ class Field: public Value_source
720730
virtual ~Field() {}
721731
/* Store functions returns 1 on overflow and -1 on fatal error */
722732
virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0;
733+
virtual int store_hex_hybrid(const char *str, uint length);
723734
virtual int store(double nr)=0;
724735
virtual int store(longlong nr, bool unsigned_val)=0;
725736
virtual int store_decimal(const my_decimal *d)=0;
@@ -1527,6 +1538,10 @@ class Field_str :public Field {
15271538
int store(longlong nr, bool unsigned_val)=0;
15281539
int store_decimal(const my_decimal *);
15291540
int store(const char *to,uint length,CHARSET_INFO *cs)=0;
1541+
int store_hex_hybrid(const char *str, uint length)
1542+
{
1543+
return store(str, length, &my_charset_bin);
1544+
}
15301545
uint repertoire(void) const
15311546
{
15321547
return my_charset_repertoire(field_charset);
@@ -2068,6 +2083,10 @@ class Field_temporal: public Field {
20682083
field_name_arg)
20692084
{ flags|= BINARY_FLAG; }
20702085
Item_result result_type () const { return STRING_RESULT; }
2086+
int store_hex_hybrid(const char *str, uint length)
2087+
{
2088+
return store(str, length, &my_charset_bin);
2089+
}
20712090
uint32 max_display_length() { return field_length; }
20722091
bool str_needs_quotes() { return TRUE; }
20732092
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }

sql/item.cc

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6079,50 +6079,6 @@ void Item_hex_constant::hex_string_init(THD *thd, const char *str,
60796079
unsigned_flag= 1;
60806080
}
60816081

6082-
longlong Item_hex_hybrid::val_int()
6083-
{
6084-
// following assert is redundant, because fixed=1 assigned in constructor
6085-
DBUG_ASSERT(fixed == 1);
6086-
char *end=(char*) str_value.ptr()+str_value.length(),
6087-
*ptr=end-MY_MIN(str_value.length(),sizeof(longlong));
6088-
6089-
ulonglong value=0;
6090-
for (; ptr != end ; ptr++)
6091-
value=(value << 8)+ (ulonglong) (uchar) *ptr;
6092-
return (longlong) value;
6093-
}
6094-
6095-
6096-
int Item_hex_hybrid::save_in_field(Field *field, bool no_conversions)
6097-
{
6098-
field->set_notnull();
6099-
if (field->result_type() == STRING_RESULT)
6100-
return field->store(str_value.ptr(), str_value.length(),
6101-
collation.collation);
6102-
6103-
ulonglong nr;
6104-
uint32 length= str_value.length();
6105-
6106-
if (length > 8)
6107-
{
6108-
nr= field->flags & UNSIGNED_FLAG ? ULONGLONG_MAX : LONGLONG_MAX;
6109-
goto warn;
6110-
}
6111-
nr= (ulonglong) val_int();
6112-
if ((length == 8) && !(field->flags & UNSIGNED_FLAG) && (nr > LONGLONG_MAX))
6113-
{
6114-
nr= LONGLONG_MAX;
6115-
goto warn;
6116-
}
6117-
return field->store((longlong) nr, TRUE); // Assume hex numbers are unsigned
6118-
6119-
warn:
6120-
if (!field->store((longlong) nr, TRUE))
6121-
field->set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE,
6122-
1);
6123-
return 1;
6124-
}
6125-
61266082

61276083
void Item_hex_hybrid::print(String *str, enum_query_type query_type)
61286084
{

sql/item.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3312,7 +3312,12 @@ class Item_hex_hybrid: public Item_hex_constant
33123312
DBUG_ASSERT(fixed == 1);
33133313
return (double) (ulonglong) Item_hex_hybrid::val_int();
33143314
}
3315-
longlong val_int();
3315+
longlong val_int()
3316+
{
3317+
// following assert is redundant, because fixed=1 assigned in constructor
3318+
DBUG_ASSERT(fixed == 1);
3319+
return longlong_from_hex_hybrid(str_value.ptr(), str_value.length());
3320+
}
33163321
my_decimal *val_decimal(my_decimal *decimal_value)
33173322
{
33183323
// following assert is redundant, because fixed=1 assigned in constructor
@@ -3321,7 +3326,11 @@ class Item_hex_hybrid: public Item_hex_constant
33213326
int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value);
33223327
return decimal_value;
33233328
}
3324-
int save_in_field(Field *field, bool no_conversions);
3329+
int save_in_field(Field *field, bool no_conversions)
3330+
{
3331+
field->set_notnull();
3332+
return field->store_hex_hybrid(str_value.ptr(), str_value.length());
3333+
}
33253334
enum Item_result cast_to_int_type() const { return INT_RESULT; }
33263335
void print(String *str, enum_query_type query_type);
33273336
};

0 commit comments

Comments
 (0)