mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-10 18:05:44 +02:00
BITPOS returns 0 for non-existent keys according to Redis's implmentation. BITPOS allows only 0 and 1 as the bit mode argument. Signed-off-by: Denis K <kalantaevskii@gmail.com>
This commit is contained in:
parent
5d2c308c99
commit
ba57145c53
2 changed files with 18 additions and 5 deletions
|
@ -548,6 +548,8 @@ void BitPos(CmdArgList args, ConnectionContext* cntx) {
|
|||
|
||||
if (!absl::SimpleAtoi(ArgS(args, 1), &value)) {
|
||||
return cntx->SendError(kInvalidIntErr);
|
||||
} else if (value != 0 && value != 1) {
|
||||
return cntx->SendError("The bit argument must be 1 or 0");
|
||||
}
|
||||
|
||||
if (args.size() >= 3) {
|
||||
|
@ -1340,11 +1342,15 @@ OpResult<int64_t> FindFirstBitWithValue(const OpArgs& op_args, std::string_view
|
|||
int64_t start, int64_t end, bool as_bit) {
|
||||
OpResult<std::string> value = ReadValue(op_args.db_cntx, key, op_args.shard);
|
||||
|
||||
std::string_view value_str;
|
||||
if (value) { // non-existent keys are treated as empty strings, per Redis
|
||||
value_str = value.value();
|
||||
// non-existent keys are handled exactly as in Redis's implementation,
|
||||
// even though it contradicts its docs:
|
||||
// If a clear bit isn't found in the specified range, the function returns -1
|
||||
// as the user specified a clear range and there are no 0 bits in that range
|
||||
if (!value) {
|
||||
return bit_value ? -1 : 0;
|
||||
}
|
||||
|
||||
std::string_view value_str = value.value();
|
||||
int64_t size = value_str.size();
|
||||
if (as_bit) {
|
||||
size *= OFFSET_FACTOR;
|
||||
|
|
|
@ -555,8 +555,15 @@ TEST_F(BitOpsFamilyTest, BitPos) {
|
|||
EXPECT_EQ(-1, CheckedInt({"bitpos", "empty", "0"}));
|
||||
EXPECT_EQ(-1, CheckedInt({"bitpos", "empty", "0", "1"}));
|
||||
|
||||
// Non-existent key should be treated like an empty string.
|
||||
EXPECT_EQ(-1, CheckedInt({"bitpos", "d", "0"}));
|
||||
// Non-existent key should be treated like padded with zeros string.
|
||||
EXPECT_EQ(-1, CheckedInt({"bitpos", "d", "1"}));
|
||||
EXPECT_EQ(0, CheckedInt({"bitpos", "d", "0"}));
|
||||
|
||||
// Make sure we accept only 0 and 1 for the bit mode arguement.
|
||||
const auto argument_must_be_0_or_1_error = ErrArg("ERR The bit argument must be 1 or 0");
|
||||
ASSERT_THAT(Run({"bitpos", "d", "2"}), argument_must_be_0_or_1_error);
|
||||
ASSERT_THAT(Run({"bitpos", "d", "42"}), argument_must_be_0_or_1_error);
|
||||
ASSERT_THAT(Run({"bitpos", "d", "-1"}), argument_must_be_0_or_1_error);
|
||||
}
|
||||
|
||||
TEST_F(BitOpsFamilyTest, BitFieldParsing) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue