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:33 UTC

[incubator-kvrocks] branch revert-1022-feat/zadd_option created (now 17f92689)

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

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


      at 17f92689 Revert "Implement the ZADD options (#1022)"

This branch includes the following new commits:

     new 17f92689 Revert "Implement the ZADD options (#1022)"

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



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

Posted by tw...@apache.org.
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")
 	})