Skip to content

Commit fa5cd7c

Browse files
committed
MDEV-10526: Add binary string support to bitwise operators
Bitwise operators (&, |, ^, ~, <<, >>) previously cast all arguments to BIGINT, silently truncating values wider than 64 bits. This broke operations on BINARY, VARBINARY, BLOB, INET6, and UUID columns. Introduces binary_mode detection in fix_length_and_dec(). When any non-literal argument has STRING_RESULT with binary charset, operators switch to byte-by-byte processing via a new Handler_str subclass, returning LONGBLOB of the same length as the input. Bare hex literals (x'FF', 0xFF) and bit literals (b'1010') retain integer mode for backward compatibility. Existing int/decimal handler classes for Item_func_bit_or and Item_func_bit_and are moved from item_cmpfunc.cc to item_func.cc for consistency. New error codes: ER_INVALID_BITWISE_OPERANDS_SIZE ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE Aggregate function support (BIT_AND/BIT_OR/BIT_XOR) to follow in a subsequent commit. Closes: MDEV-10526
1 parent f29bd54 commit fa5cd7c

4 files changed

Lines changed: 620 additions & 69 deletions

File tree

sql/item_cmpfunc.cc

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4920,74 +4920,6 @@ void Item_func_in::mark_as_condition_AND_part(TABLE_LIST *embedding)
49204920
}
49214921

49224922

4923-
class Func_handler_bit_or_int_to_ulonglong:
4924-
public Item_handled_func::Handler_ulonglong
4925-
{
4926-
public:
4927-
Longlong_null to_longlong_null(Item_handled_func *item) const override
4928-
{
4929-
DBUG_ASSERT(item->fixed());
4930-
Longlong_null a= item->arguments()[0]->to_longlong_null();
4931-
return a.is_null() ? a : a | item->arguments()[1]->to_longlong_null();
4932-
}
4933-
};
4934-
4935-
4936-
class Func_handler_bit_or_dec_to_ulonglong:
4937-
public Item_handled_func::Handler_ulonglong
4938-
{
4939-
public:
4940-
Longlong_null to_longlong_null(Item_handled_func *item) const override
4941-
{
4942-
DBUG_ASSERT(item->fixed());
4943-
VDec a(item->arguments()[0]);
4944-
return a.is_null() ? Longlong_null() :
4945-
a.to_xlonglong_null() | VDec(item->arguments()[1]).to_xlonglong_null();
4946-
}
4947-
};
4948-
4949-
4950-
bool Item_func_bit_or::fix_length_and_dec(THD *thd)
4951-
{
4952-
static Func_handler_bit_or_int_to_ulonglong ha_int_to_ull;
4953-
static Func_handler_bit_or_dec_to_ulonglong ha_dec_to_ull;
4954-
return fix_length_and_dec_op2_std(&ha_int_to_ull, &ha_dec_to_ull);
4955-
}
4956-
4957-
4958-
class Func_handler_bit_and_int_to_ulonglong:
4959-
public Item_handled_func::Handler_ulonglong
4960-
{
4961-
public:
4962-
Longlong_null to_longlong_null(Item_handled_func *item) const override
4963-
{
4964-
DBUG_ASSERT(item->fixed());
4965-
Longlong_null a= item->arguments()[0]->to_longlong_null();
4966-
return a.is_null() ? a : a & item->arguments()[1]->to_longlong_null();
4967-
}
4968-
};
4969-
4970-
4971-
class Func_handler_bit_and_dec_to_ulonglong:
4972-
public Item_handled_func::Handler_ulonglong
4973-
{
4974-
public:
4975-
Longlong_null to_longlong_null(Item_handled_func *item) const override
4976-
{
4977-
DBUG_ASSERT(item->fixed());
4978-
VDec a(item->arguments()[0]);
4979-
return a.is_null() ? Longlong_null() :
4980-
a.to_xlonglong_null() & VDec(item->arguments()[1]).to_xlonglong_null();
4981-
}
4982-
};
4983-
4984-
4985-
bool Item_func_bit_and::fix_length_and_dec(THD *thd)
4986-
{
4987-
static Func_handler_bit_and_int_to_ulonglong ha_int_to_ull;
4988-
static Func_handler_bit_and_dec_to_ulonglong ha_dec_to_ull;
4989-
return fix_length_and_dec_op2_std(&ha_int_to_ull, &ha_dec_to_ull);
4990-
}
49914923

49924924
Item_cond::Item_cond(THD *thd, Item_cond *item)
49934925
:Item_bool_func(thd, item),

0 commit comments

Comments
 (0)