8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 21:23:04 +01:00
This commit is contained in:
AlexPeshkoff 2021-05-14 11:35:36 +03:00
parent 629b9ea74f
commit 6a0135c9ec
4 changed files with 34 additions and 3 deletions

View File

@ -2872,6 +2872,16 @@ SSHORT CVT_decompose(const char* str, USHORT len, Int128* val, ErrorFunction err
}
Int128 CVT_hex_to_int128(const char* str, USHORT len)
{
Int128 val;
RetValue<I128Traits> value(&val);
hex_to_value(str, str + len, &value);
return val;
}
USHORT CVT_get_string_ptr_common(const dsc* desc, USHORT* ttype, UCHAR** address,
vary* temp, USHORT length, DecimalStatus decSt, Callbacks* cb)
{
@ -3538,7 +3548,7 @@ static void hex_to_value(const char*& string, const char* end, RetPtr* retValue)
* Functional description
* Convert a hex string to a numeric value. This code only
* converts a hex string into a numeric value, and the
* biggest hex string supported must fit into a BIGINT.
* size of biggest hex string depends upon RetPtr.
*
*************************************/
{

View File

@ -93,6 +93,7 @@ double CVT_get_double(const dsc*, Firebird::DecimalStatus, ErrorFunction, bool*
Firebird::Decimal64 CVT_get_dec64(const dsc*, Firebird::DecimalStatus, ErrorFunction);
Firebird::Decimal128 CVT_get_dec128(const dsc*, Firebird::DecimalStatus, ErrorFunction);
Firebird::Int128 CVT_get_int128(const dsc*, SSHORT, Firebird::DecimalStatus, ErrorFunction);
Firebird::Int128 CVT_hex_to_int128(const char* str, USHORT len);
USHORT CVT_make_string(const dsc*, USHORT, const char**, vary*, USHORT, Firebird::DecimalStatus, ErrorFunction);
void CVT_make_null_string(const dsc*, USHORT, const char**, vary*, USHORT, Firebird::DecimalStatus, ErrorFunction);
void CVT_move_common(const dsc*, dsc*, Firebird::DecimalStatus, Firebird::Callbacks*);

View File

@ -861,7 +861,7 @@ int Parser::yylexAux()
++charlen; // Okay, just count 'em
++lex.ptr; // and advance...
if (charlen > 16) // Too many digits...
if (charlen > 32) // Too many digits...
{
hexerror = true;
break;
@ -872,11 +872,24 @@ int Parser::yylexAux()
// an NUMBER32BIT or NUMBER64BIT.
if (!hexerror)
{
if (charlen > 16)
{
// we deal with int128
fb_assert(charlen <= 32); // charlen is always <= 32, see 10-15 lines upper
Firebird::string sbuff(hexstring, charlen);
sbuff.insert(0, "0X");
yylval.lim64ptr = newLim64String(sbuff, 0);
return TOK_NUM128;
}
// if charlen > 8 (something like FFFF FFFF 0, w/o the spaces)
// then we have to return a NUMBER64BIT. We'll make a string
// node here, and let make.cpp worry about converting the
// string to a number and building the node later.
if (charlen > 8)
else if (charlen > 8)
{
char cbuff[32];
fb_assert(charlen <= 16); // charlen is always <= 16, see 10-15 lines upper

View File

@ -218,6 +218,13 @@ UCHAR CVT_get_numeric(const UCHAR* string, const USHORT length, SSHORT* scale, v
bool digit_seen = false, fraction = false, over = false;
const UCHAR* p = string;
if (p[0] == '0' && p[1] == 'X')
{
*(Int128*) ptr = CVT_hex_to_int128(reinterpret_cast<const char*>(p + 2), length - 2);
*scale = 0;
return dtype_int128;
}
const UCHAR* const end = p + length;
for (; p < end; p++)
{