diff --git a/src/facade/op_status.cc b/src/facade/op_status.cc index 6441a2ba7..d89285870 100644 --- a/src/facade/op_status.cc +++ b/src/facade/op_status.cc @@ -28,6 +28,8 @@ std::string_view StatusToMsg(OpStatus status) { return "-BUSYGROUP Consumer Group name already exists"; case OpStatus::INVALID_NUMERIC_RESULT: return kInvalidNumericResult; + case OpStatus::AT_LEAST_ONE_KEY: + return "at least 1 input key is needed for this command"; default: LOG(ERROR) << "Unsupported status " << status; return "Internal error"; diff --git a/src/facade/op_status.h b/src/facade/op_status.h index 0f175afc2..f96fdba7c 100644 --- a/src/facade/op_status.h +++ b/src/facade/op_status.h @@ -27,6 +27,7 @@ enum class OpStatus : uint16_t { ENTRIES_ADDED_SMALL, INVALID_NUMERIC_RESULT, CANCELLED, + AT_LEAST_ONE_KEY, }; class OpResultBase { diff --git a/src/server/transaction.cc b/src/server/transaction.cc index b3b4972a0..795de10ba 100644 --- a/src/server/transaction.cc +++ b/src/server/transaction.cc @@ -1462,12 +1462,10 @@ OpResult DetermineKeys(const CommandId* cid, CmdArgList args) { if (!absl::SimpleAtoi(num, &num_custom_keys) || num_custom_keys < 0) return OpStatus::INVALID_INT; - if (name == "ZDIFF" && num_custom_keys == 0) { - return OpStatus::INVALID_INT; - } - - if (name == "ZUNION" && num_custom_keys == 0) { - return OpStatus::SYNTAX_ERR; + if (num_custom_keys == 0 && + (absl::StartsWith(name, "ZDIFF") || absl::StartsWith(name, "ZUNION") || + absl::StartsWith(name, "ZINTER"))) { + return OpStatus::AT_LEAST_ONE_KEY; } if (args.size() < size_t(num_custom_keys) + num_keys_index + 1) diff --git a/src/server/zset_family_test.cc b/src/server/zset_family_test.cc index a5c442ab4..f0f5a22e2 100644 --- a/src/server/zset_family_test.cc +++ b/src/server/zset_family_test.cc @@ -322,7 +322,7 @@ TEST_F(ZSetFamilyTest, ZUnionError) { EXPECT_THAT(resp, ErrArg("wrong number of arguments")); resp = Run({"zunion", "0", "myset"}); - EXPECT_THAT(resp, ErrArg("syntax error")); + EXPECT_THAT(resp, ErrArg("at least 1 input key is needed")); resp = Run({"zunion", "3", "z1", "z2", "z3", "weights", "1", "1", "k"}); EXPECT_THAT(resp, ErrArg("weight value is not a float")); @@ -402,7 +402,7 @@ TEST_F(ZSetFamilyTest, ZUnionStore) { EXPECT_THAT(resp, ErrArg("wrong number of arguments")); resp = Run({"zunionstore", "key", "0", "aggregate"}); - EXPECT_THAT(resp, ErrArg("syntax error")); + EXPECT_THAT(resp, ErrArg("at least 1 input key is needed")); resp = Run({"zunionstore", "key", "0", "aggregate", "sum"}); EXPECT_THAT(resp, ErrArg("at least 1 input key is needed")); @@ -476,11 +476,12 @@ TEST_F(ZSetFamilyTest, ZInterStore) { TEST_F(ZSetFamilyTest, ZInterCard) { EXPECT_EQ(3, CheckedInt({"zadd", "z1", "1", "a", "2", "b", "3", "c"})); EXPECT_EQ(3, CheckedInt({"zadd", "z2", "2", "b", "3", "c", "4", "d"})); - RespExpr resp; EXPECT_EQ(2, CheckedInt({"zintercard", "2", "z1", "z2"})); EXPECT_EQ(1, CheckedInt({"zintercard", "2", "z1", "z2", "LIMIT", "1"})); + RespExpr resp; + resp = Run({"zintercard", "2", "z1", "z2", "LIM"}); EXPECT_THAT(resp, ErrArg("syntax error")); resp = Run({"zintercard", "2", "z1", "z2", "LIMIT"}); @@ -488,6 +489,9 @@ TEST_F(ZSetFamilyTest, ZInterCard) { resp = Run({"zintercard", "2", "z1", "z2", "LIMIT", "a"}); EXPECT_THAT(resp, ErrArg("limit value is not a positive integer")); + resp = Run({"zintercard", "0", "z1"}); + EXPECT_THAT(resp, ErrArg("at least 1 input")); + // support for sets EXPECT_EQ(3, CheckedInt({"sadd", "s2", "b", "c", "d"})); EXPECT_EQ(2, CheckedInt({"zintercard", "2", "z1", "s2"})); @@ -632,10 +636,10 @@ TEST_F(ZSetFamilyTest, ZDiffError) { EXPECT_THAT(resp, ErrArg("wrong number of arguments")); resp = Run({"zdiff", "0", "z1"}); - EXPECT_THAT(resp, ErrArg("value is not an integer or out of range")); + EXPECT_THAT(resp, ErrArg("at least 1 input key is needed")); resp = Run({"zdiff", "0", "z1", "z2"}); - EXPECT_THAT(resp, ErrArg("value is not an integer or out of range")); + EXPECT_THAT(resp, ErrArg("at least 1 input key is needed")); } TEST_F(ZSetFamilyTest, ZDiff) {