You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kvrocks.apache.org by tw...@apache.org on 2022/10/28 05:57:34 UTC

[incubator-kvrocks] 01/01: Revert "Implement the ZADD options (#1022)"

This is an automated email from the ASF dual-hosted git repository.

twice pushed a commit to branch revert-1022-feat/zadd_option
in repository https://gitbox.apache.org/repos/asf/incubator-kvrocks.git

commit 17f92689d8805e8cbfcb81382e8681f5f872de1e
Author: Twice <tw...@apache.org>
AuthorDate: Fri Oct 28 05:57:29 2022 +0000

    Revert "Implement the ZADD options (#1022)"
    
    This reverts commit 30a0348636a79034c464e2f8cbda2d10dec49ce8.
---
 src/commands/redis_cmd.cc                | 64 +++------------------------
 src/types/redis_geo.cc                   |  4 +-
 src/types/redis_zset.cc                  | 24 ++--------
 src/types/redis_zset.h                   | 27 +-----------
 tests/cppunit/compact_test.cc            |  2 +-
 tests/cppunit/disk_test.cc               |  2 +-
 tests/cppunit/t_zset_test.cc             | 30 ++++++-------
 tests/gocase/unit/type/zset/zset_test.go | 76 --------------------------------
 8 files changed, 29 insertions(+), 200 deletions(-)

diff --git a/src/commands/redis_cmd.cc b/src/commands/redis_cmd.cc
index 1f98e64f..903ca8fa 100644
--- a/src/commands/redis_cmd.cc
+++ b/src/commands/redis_cmd.cc
@@ -74,7 +74,6 @@ const char *errUnbalancedStreamList =
     "Unbalanced XREAD list of streams: for each stream key an ID or '$' must be specified.";
 const char *errTimeoutIsNegative = "timeout is negative";
 const char *errLimitOptionNotAllowed = "syntax error, LIMIT cannot be used without the special ~ option";
-const char *errZSetLTGTNX = "GT, LT, and/or NX options at the same time are not compatible";
 
 enum class AuthResult {
   OK,
@@ -2378,20 +2377,12 @@ class CommandSInterStore : public Commander {
 class CommandZAdd : public Commander {
  public:
   Status Parse(const std::vector<std::string> &args) override {
-    unsigned index = 2;
-    parseFlags(args, index);
-    if (auto s = validateFlags(); !s.IsOK()) {
-      return s;
-    }
-    if (auto left = (args.size() - index); left >= 0) {
-      if (flags_.HasIncr() && left != 2) {
-        return Status(Status::RedisParseErr, "INCR option supports a single increment-element pair");
-      } else if (left % 2 != 0 || left == 0) {
-        return Status(Status::RedisParseErr, errInvalidSyntax);
-      }
+    if (args.size() % 2 != 0) {
+      return Status(Status::RedisParseErr, errInvalidSyntax);
     }
+
     try {
-      for (unsigned i = index; i < args.size(); i += 2) {
+      for (unsigned i = 2; i < args.size(); i += 2) {
         double score = std::stod(args[i]);
         if (std::isnan(score)) {
           return Status(Status::RedisParseErr, "ERR score is not a valid float");
@@ -2406,62 +2397,19 @@ class CommandZAdd : public Commander {
 
   Status Execute(Server *svr, Connection *conn, std::string *output) override {
     int ret;
-    double old_score = member_scores_[0].score;
     Redis::ZSet zset_db(svr->storage_, conn->GetNamespace());
-    rocksdb::Status s = zset_db.Add(args_[1], flags_, &member_scores_, &ret);
+    rocksdb::Status s = zset_db.Add(args_[1], 0, &member_scores_, &ret);
     if (!s.ok()) {
       return Status(Status::RedisExecErr, s.ToString());
     }
-    if (flags_.HasIncr()) {
-      auto new_score = member_scores_[0].score;
-      if ((flags_.HasNX() || flags_.HasXX() || flags_.HasLT() || flags_.HasGT()) && old_score == new_score &&
-          ret == 0) {  // not the first time using incr && score not changed
-        *output = Redis::NilString();
-        return Status::OK();
-      }
-      *output = Redis::BulkString(Util::Float2String(new_score));
-    } else {
-      *output = Redis::Integer(ret);
-    }
+    *output = Redis::Integer(ret);
     return Status::OK();
   }
 
  private:
   std::vector<MemberScore> member_scores_;
-  ZAddFlags flags_{0};
-
-  void parseFlags(const std::vector<std::string> &args, unsigned &index);
-  Status validateFlags() const;
 };
 
-void CommandZAdd::parseFlags(const std::vector<std::string> &args, unsigned &index) {
-  std::unordered_map<std::string, ZSetFlags> options = {{"xx", kZSetXX}, {"nx", kZSetNX}, {"ch", kZSetCH},
-                                                        {"lt", kZSetLT}, {"gt", kZSetGT}, {"incr", kZSetIncr}};
-  for (unsigned i = 2; i < args.size(); i++) {
-    auto option = Util::ToLower(args[i]);
-    auto it = options.find(option);
-    if (it != options.end()) {
-      flags_.SetFlag(it->second);
-      index++;
-    } else {
-      break;
-    }
-  }
-}
-
-Status CommandZAdd::validateFlags() const {
-  if (!flags_.HasAnyFlags()) {
-    return Status::OK();
-  }
-  if (flags_.HasNX() && flags_.HasXX()) {
-    return Status(Status::RedisParseErr, "XX and NX options at the same time are not compatible");
-  }
-  if ((flags_.HasLT() && flags_.HasGT()) || (flags_.HasLT() && flags_.HasNX()) || (flags_.HasGT() && flags_.HasNX())) {
-    return Status(Status::RedisParseErr, errZSetLTGTNX);
-  }
-  return Status::OK();
-}
-
 class CommandZCount : public Commander {
  public:
   Status Parse(const std::vector<std::string> &args) override {
diff --git a/src/types/redis_geo.cc b/src/types/redis_geo.cc
index 0400eddc..293ca377 100644
--- a/src/types/redis_geo.cc
+++ b/src/types/redis_geo.cc
@@ -35,7 +35,7 @@ rocksdb::Status Geo::Add(const Slice &user_key, std::vector<GeoPoint> *geo_point
     GeoHashFix52Bits bits = GeoHashHelper::Align52Bits(hash);
     member_scores.emplace_back(MemberScore{geo_point.member, static_cast<double>(bits)});
   }
-  return ZSet::Add(user_key, ZAddFlags::Default(), &member_scores, ret);
+  return ZSet::Add(user_key, 0, &member_scores, ret);
 }
 
 rocksdb::Status Geo::Dist(const Slice &user_key, const Slice &member_1, const Slice &member_2, double *dist) {
@@ -120,7 +120,7 @@ rocksdb::Status Geo::Radius(const Slice &user_key, double longitude, double lati
         member_scores.emplace_back(MemberScore{geo_point.member, score});
       }
       int ret;
-      ZSet::Add(store_key, ZAddFlags::Default(), &member_scores, &ret);
+      ZSet::Add(store_key, 0, &member_scores, &ret);
     }
   }
 
diff --git a/src/types/redis_zset.cc b/src/types/redis_zset.cc
index 558f25ab..63d2a9a8 100644
--- a/src/types/redis_zset.cc
+++ b/src/types/redis_zset.cc
@@ -37,7 +37,7 @@ rocksdb::Status ZSet::GetMetadata(const Slice &ns_key, ZSetMetadata *metadata) {
   return Database::GetMetadata(kRedisZSet, ns_key, metadata);
 }
 
-rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, std::vector<MemberScore> *mscores, int *ret) {
+rocksdb::Status ZSet::Add(const Slice &user_key, uint8_t flags, std::vector<MemberScore> *mscores, int *ret) {
   *ret = 0;
 
   std::string ns_key;
@@ -49,7 +49,6 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, std::vector<Me
   if (!s.ok() && !s.IsNotFound()) return s;
 
   int added = 0;
-  int changed = 0;
   rocksdb::WriteBatch batch;
   WriteBatchLogData log_data(kRedisZSet);
   batch.PutLogData(log_data.Encode());
@@ -77,24 +76,14 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, std::vector<Me
       s = db_->Get(rocksdb::ReadOptions(), member_key, &old_score_bytes);
       if (!s.ok() && !s.IsNotFound()) return s;
       if (s.ok()) {
-        if (!s.IsNotFound() && flags.HasNX()) {
-          continue;
-        }
         double old_score = DecodeDouble(old_score_bytes.data());
-        if (flags.HasIncr()) {
-          if ((flags.HasLT() && (*mscores)[i].score >= 0) || (flags.HasGT() && (*mscores)[i].score <= 0)) {
-            continue;
-          }
+        if (flags == kZSetIncr) {
           (*mscores)[i].score += old_score;
           if (std::isnan((*mscores)[i].score)) {
             return rocksdb::Status::InvalidArgument("resulting score is not a number (NaN)");
           }
         }
         if ((*mscores)[i].score != old_score) {
-          if ((flags.HasLT() && (*mscores)[i].score >= old_score) ||
-              (flags.HasGT() && (*mscores)[i].score <= old_score)) {
-            continue;
-          }
           old_score_bytes.append((*mscores)[i].member);
           std::string old_score_key;
           InternalKey(ns_key, old_score_bytes, metadata.version, storage_->IsSlotIdEncoded()).Encode(&old_score_key);
@@ -105,14 +94,10 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, std::vector<Me
           new_score_bytes.append((*mscores)[i].member);
           InternalKey(ns_key, new_score_bytes, metadata.version, storage_->IsSlotIdEncoded()).Encode(&new_score_key);
           batch.Put(score_cf_handle_, new_score_key, Slice());
-          changed++;
         }
         continue;
       }
     }
-    if (flags.HasXX()) {
-      continue;
-    }
     std::string score_bytes, score_key;
     PutDouble(&score_bytes, (*mscores)[i].score);
     batch.Put(member_key, score_bytes);
@@ -128,9 +113,6 @@ rocksdb::Status ZSet::Add(const Slice &user_key, ZAddFlags flags, std::vector<Me
     metadata.Encode(&bytes);
     batch.Put(metadata_cf_handle_, ns_key, bytes);
   }
-  if (flags.HasCH()) {
-    *ret += changed;
-  }
   return storage_->Write(storage_->DefaultWriteOptions(), &batch);
 }
 
@@ -156,7 +138,7 @@ rocksdb::Status ZSet::IncrBy(const Slice &user_key, const Slice &member, double
   int ret;
   std::vector<MemberScore> mscores;
   mscores.emplace_back(MemberScore{member.ToString(), increment});
-  rocksdb::Status s = Add(user_key, ZAddFlags::Incr(), &mscores, &ret);
+  rocksdb::Status s = Add(user_key, kZSetIncr, &mscores, &ret);
   if (!s.ok()) return s;
   *score = mscores[0].score;
   return rocksdb::Status::OK();
diff --git a/src/types/redis_zset.h b/src/types/redis_zset.h
index b97e98be..42b3fd5b 100644
--- a/src/types/redis_zset.h
+++ b/src/types/redis_zset.h
@@ -82,31 +82,6 @@ enum ZSetFlags {
   kZSetXX = 1 << 2,
   kZSetReversed = 1 << 3,
   kZSetRemoved = 1 << 4,
-  kZSetGT = 1 << 5,
-  kZSetLT = 1 << 6,
-  kZSetCH = 1 << 7,
-};
-
-class ZAddFlags {
- public:
-  explicit ZAddFlags(uint8_t flags = 0) : flags(flags) {}
-
-  bool HasNX() const { return (flags & kZSetNX) != 0; }
-  bool HasXX() const { return (flags & kZSetXX) != 0; }
-  bool HasLT() const { return (flags & kZSetLT) != 0; }
-  bool HasGT() const { return (flags & kZSetGT) != 0; }
-  bool HasCH() const { return (flags & kZSetCH) != 0; }
-  bool HasIncr() const { return (flags & kZSetIncr) != 0; }
-  bool HasAnyFlags() const { return flags != 0; }
-
-  void SetFlag(ZSetFlags setFlags) { flags |= setFlags; }
-
-  static const ZAddFlags Incr() { return ZAddFlags{kZSetIncr}; }
-
-  static const ZAddFlags Default() { return ZAddFlags{0}; }
-
- private:
-  uint8_t flags = 0;
 };
 
 namespace Redis {
@@ -115,7 +90,7 @@ class ZSet : public SubKeyScanner {
  public:
   explicit ZSet(Engine::Storage *storage, const std::string &ns)
       : SubKeyScanner(storage, ns), score_cf_handle_(storage->GetCFHandle("zset_score")) {}
-  rocksdb::Status Add(const Slice &user_key, ZAddFlags flags, std::vector<MemberScore> *mscores, int *ret);
+  rocksdb::Status Add(const Slice &user_key, uint8_t flags, std::vector<MemberScore> *mscores, int *ret);
   rocksdb::Status Card(const Slice &user_key, int *ret);
   rocksdb::Status Count(const Slice &user_key, const ZRangeSpec &spec, int *ret);
   rocksdb::Status IncrBy(const Slice &user_key, const Slice &member, double increment, double *score);
diff --git a/tests/cppunit/compact_test.cc b/tests/cppunit/compact_test.cc
index 1c75e04f..4042e885 100644
--- a/tests/cppunit/compact_test.cc
+++ b/tests/cppunit/compact_test.cc
@@ -75,7 +75,7 @@ TEST(Compact, Filter) {
   auto zset = std::make_unique<Redis::ZSet>(storage_.get(), ns);
   std::string expired_zset_key = "expire_zset_key";
   std::vector<MemberScore> member_scores = {MemberScore{"z1", 1.1}, MemberScore{"z2", 0.4}};
-  zset->Add(expired_zset_key, ZAddFlags::Default(), &member_scores, &ret);
+  zset->Add(expired_zset_key, 0, &member_scores, &ret);
   zset->Expire(expired_zset_key, 1);  // expired
   usleep(10000);
 
diff --git a/tests/cppunit/disk_test.cc b/tests/cppunit/disk_test.cc
index 5472c5b9..ca252df4 100644
--- a/tests/cppunit/disk_test.cc
+++ b/tests/cppunit/disk_test.cc
@@ -148,7 +148,7 @@ TEST_F(RedisDiskTest, ZsetDisk) {
     mscores[i].score = 1.0 * value_size[int(values_.size()) - i - 1];
     approximate_size += (key_.size() + 8 + mscores[i].member.size() + 8) * 2;
   }
-  rocksdb::Status s = zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  rocksdb::Status s = zset->Add(key_, 0, &mscores, &ret);
   EXPECT_TRUE(s.ok() && ret == 5);
   uint64_t key_size = 0;
   EXPECT_TRUE(disk->GetKeySize(key_, kRedisZSet, &key_size).ok());
diff --git a/tests/cppunit/t_zset_test.cc b/tests/cppunit/t_zset_test.cc
index 288fbe11..d750ab0a 100644
--- a/tests/cppunit/t_zset_test.cc
+++ b/tests/cppunit/t_zset_test.cc
@@ -47,14 +47,14 @@ TEST_F(RedisZSetTest, Add) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size()), ret);
   for (size_t i = 0; i < fields_.size(); i++) {
     double got;
     rocksdb::Status s = zset->Score(key_, fields_[i], &got);
     EXPECT_EQ(scores_[i], got);
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(ret, 0);
   zset->Del(key_);
 }
@@ -65,7 +65,7 @@ TEST_F(RedisZSetTest, IncrBy) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   for (size_t i = 0; i < fields_.size(); i++) {
     double increment = 12.3, score;
@@ -81,7 +81,7 @@ TEST_F(RedisZSetTest, Remove) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   zset->Remove(key_, fields_, &ret);
   EXPECT_EQ(fields_.size(), ret);
@@ -100,7 +100,7 @@ TEST_F(RedisZSetTest, Range) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
   int count = mscores.size() - 1;
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   zset->Range(key_, 0, -2, 0, &mscores);
   EXPECT_EQ(mscores.size(), count);
@@ -118,7 +118,7 @@ TEST_F(RedisZSetTest, RevRange) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
   int count = mscores.size() - 1;
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size()), ret);
   zset->Range(key_, 0, -2, kZSetReversed, &mscores);
   EXPECT_EQ(mscores.size(), count);
@@ -135,7 +135,7 @@ TEST_F(RedisZSetTest, PopMin) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size()), ret);
   zset->Pop(key_, mscores.size() - 1, true, &mscores);
   for (size_t i = 0; i < mscores.size(); i++) {
@@ -154,7 +154,7 @@ TEST_F(RedisZSetTest, PopMax) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size()), ret);
   zset->Pop(key_, mscores.size() - 1, false, &mscores);
   for (size_t i = 0; i < mscores.size(); i++) {
@@ -171,7 +171,7 @@ TEST_F(RedisZSetTest, RangeByLex) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
 
   ZRangeLexSpec spec;
@@ -227,7 +227,7 @@ TEST_F(RedisZSetTest, RangeByScore) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
 
   // test case: inclusive the min and max score
@@ -275,7 +275,7 @@ TEST_F(RedisZSetTest, RangeByScoreWithLimit) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
 
   ZRangeSpec spec;
@@ -296,7 +296,7 @@ TEST_F(RedisZSetTest, RemRangeByScore) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   ZRangeSpec spec;
   spec.min = scores_[0];
@@ -315,7 +315,7 @@ TEST_F(RedisZSetTest, RemoveRangeByRank) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   zset->RemoveRangeByRank(key_, 0, fields_.size() - 2, &ret);
   EXPECT_EQ(fields_.size() - 1, ret);
@@ -329,7 +329,7 @@ TEST_F(RedisZSetTest, RemoveRevRangeByRank) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(fields_.size(), ret);
   zset->RemoveRangeByRank(key_, 0, fields_.size() - 2, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size() - 1), ret);
@@ -343,7 +343,7 @@ TEST_F(RedisZSetTest, Rank) {
   for (size_t i = 0; i < fields_.size(); i++) {
     mscores.emplace_back(MemberScore{fields_[i].ToString(), scores_[i]});
   }
-  zset->Add(key_, ZAddFlags::Default(), &mscores, &ret);
+  zset->Add(key_, 0, &mscores, &ret);
   EXPECT_EQ(static_cast<int>(fields_.size()), ret);
 
   for (size_t i = 0; i < fields_.size(); i++) {
diff --git a/tests/gocase/unit/type/zset/zset_test.go b/tests/gocase/unit/type/zset/zset_test.go
index 7dae9e62..616387e1 100644
--- a/tests/gocase/unit/type/zset/zset_test.go
+++ b/tests/gocase/unit/type/zset/zset_test.go
@@ -93,82 +93,6 @@ func basicTests(t *testing.T, rdb *redis.Client, ctx context.Context, encoding s
 		require.Equal(t, float64(30), rdb.ZScore(ctx, "ztmp", "x").Val())
 	})
 
-	t.Run(fmt.Sprintf("ZSET ZADD INCR option supports a single pair - %s", encoding), func(t *testing.T) {
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, 1.5, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Contains(t, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{Members: []redis.Z{{Member: "abc", Score: 1.5}, {Member: "adc"}}}).Err(),
-			"INCR option supports a single increment-element pair")
-	})
-
-	t.Run(fmt.Sprintf("ZSET ZADD IncrMixedOtherOptions - %s", encoding), func(t *testing.T) {
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, "1.5", rdb.Do(ctx, "zadd", "ztmp", "nx", "nx", "nx", "nx", "incr", "1.5", "abc").Val())
-		require.Equal(t, redis.Nil, rdb.Do(ctx, "zadd", "ztmp", "nx", "nx", "nx", "nx", "incr", "1.5", "abc").Err())
-		require.Equal(t, "3", rdb.Do(ctx, "zadd", "ztmp", "xx", "xx", "xx", "xx", "incr", "1.5", "abc").Val())
-
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, 1.5, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Equal(t, redis.Nil, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Err())
-
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, redis.Nil, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{XX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Err())
-		require.Equal(t, 1.5, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, 1.5, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Equal(t, 3.0, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{GT: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Equal(t, 0.0, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{GT: true, Members: []redis.Z{{Member: "abc", Score: -1.5}}}).Val())
-		require.Equal(t, redis.Nil, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{GT: true, Members: []redis.Z{{Member: "abc", Score: -1.5}}}).Err())
-
-		rdb.Del(ctx, "ztmp")
-		require.Equal(t, 1.5, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Equal(t, 0.0, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{LT: true, Members: []redis.Z{{Member: "abc", Score: -1.5}}}).Val())
-		require.Equal(t, 0.0, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{LT: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.Equal(t, redis.Nil, rdb.ZAddArgsIncr(ctx, "ztmp", redis.ZAddArgs{LT: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Err())
-	})
-
-	t.Run(fmt.Sprintf("ZSET ZADD LT/GT with other options - %s", encoding), func(t *testing.T) {
-		rdb.Del(ctx, "ztmp")
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{GT: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 2.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{GT: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 2.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{GT: true, Ch: false, Members: []redis.Z{{Member: "abc", Score: 2.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{GT: true, Ch: false, Members: []redis.Z{{Member: "abc", Score: 100}}}).Val())
-		require.Contains(t, rdb.Do(ctx, "zadd", "ztmp", "lt", "gt", "1", "m1", "2", "m2").Err(),
-			"GT, LT, and/or NX options at the same time are not compatible")
-
-		rdb.Del(ctx, "ztmp")
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{LT: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{LT: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 1.2}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{LT: true, Ch: false, Members: []redis.Z{{Member: "abc", Score: 0.5}}}).Val())
-
-		rdb.Del(ctx, "newAbc1", "newAbc2")
-		require.EqualValues(t, 2, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{Ch: true, Members: []redis.Z{{Member: "abc", Score: 0.5}, {Member: "newAbc1", Score: 10}, {Member: "newAbc2"}}}).Val())
-	})
-
-	t.Run(fmt.Sprintf("ZSET ZADD NX/XX option supports a single pair - %s", encoding), func(t *testing.T) {
-		rdb.Del(ctx, "ztmp")
-		require.EqualValues(t, 2, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "a", Score: 1}, {Member: "b", Score: 2}}}).Val())
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "c", Score: 3}}}).Val())
-
-		rdb.Del(ctx, "ztmp")
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{XX: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 2.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{XX: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 2.5}}}).Val())
-		require.Contains(t, rdb.Do(ctx, "zadd", "ztmp", "nx", "xx", "1", "m1", "2", "m2").Err(),
-			"XX and NX options at the same time are not compatible")
-
-		require.Contains(t, rdb.Do(ctx, "zadd", "ztmp", "lt", "nx", "1", "m1", "2", "m2").Err(),
-			"GT, LT, and/or NX options at the same time are not compatible")
-		require.Contains(t, rdb.Do(ctx, "zadd", "ztmp", "gt", "nx", "1", "m1", "2", "m2").Err(),
-			"GT, LT, and/or NX options at the same time are not compatible")
-
-		rdb.Del(ctx, "ztmp")
-		require.EqualValues(t, 1, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Ch: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-		require.EqualValues(t, 0, rdb.ZAddArgs(ctx, "ztmp", redis.ZAddArgs{NX: true, Members: []redis.Z{{Member: "abc", Score: 1.5}}}).Val())
-	})
-
 	t.Run(fmt.Sprintf("ZSET element can't be set to NaN with ZADD - %s", encoding), func(t *testing.T) {
 		require.Contains(t, rdb.ZAdd(ctx, "myzset", redis.Z{Score: math.NaN(), Member: "abc"}).Err(), "float")
 	})