fix(server): Do not return empty array after expiration (#2104)

Fixes #2102
This commit is contained in:
Shahar Mike 2023-11-02 08:36:58 +02:00 committed by GitHub
parent 00f1e3d578
commit 1491bf4cfe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 12 additions and 4 deletions

View file

@ -542,7 +542,6 @@ OpResult<vector<string>> OpGetAll(const OpArgs& op_args, string_view key, uint8_
vector<string> res; vector<string> res;
bool keyval = (mask == (FIELDS | VALUES)); bool keyval = (mask == (FIELDS | VALUES));
unsigned index = 0;
if (pv.Encoding() == kEncodingListPack) { if (pv.Encoding() == kEncodingListPack) {
uint8_t* lp = (uint8_t*)pv.RObjPtr(); uint8_t* lp = (uint8_t*)pv.RObjPtr();
@ -551,6 +550,7 @@ OpResult<vector<string>> OpGetAll(const OpArgs& op_args, string_view key, uint8_
uint8_t* fptr = lpFirst(lp); uint8_t* fptr = lpFirst(lp);
uint8_t intbuf[LP_INTBUF_SIZE]; uint8_t intbuf[LP_INTBUF_SIZE];
unsigned index = 0;
while (fptr) { while (fptr) {
if (mask & FIELDS) { if (mask & FIELDS) {
res[index++] = LpGetView(fptr, intbuf); res[index++] = LpGetView(fptr, intbuf);
@ -565,14 +565,15 @@ OpResult<vector<string>> OpGetAll(const OpArgs& op_args, string_view key, uint8_
DCHECK_EQ(pv.Encoding(), kEncodingStrMap2); DCHECK_EQ(pv.Encoding(), kEncodingStrMap2);
StringMap* sm = GetStringMap(pv, op_args.db_cntx); StringMap* sm = GetStringMap(pv, op_args.db_cntx);
res.resize(sm->Size() * (keyval ? 2 : 1)); // Some items could have expired, yet accounted for in Size(), so reserve() might overshoot
res.reserve(sm->Size() * (keyval ? 2 : 1));
for (const auto& k_v : *sm) { for (const auto& k_v : *sm) {
if (mask & FIELDS) { if (mask & FIELDS) {
res[index++].assign(k_v.first, sdslen(k_v.first)); res.emplace_back(k_v.first, sdslen(k_v.first));
} }
if (mask & VALUES) { if (mask & VALUES) {
res[index++].assign(k_v.second, sdslen(k_v.second)); res.emplace_back(k_v.second, sdslen(k_v.second));
} }
} }
} }

View file

@ -332,4 +332,11 @@ TEST_F(HSetFamilyTest, Issue1140) {
EXPECT_EQ("Bar", Run({"HGET", "CaseKey", "Foo"})); EXPECT_EQ("Bar", Run({"HGET", "CaseKey", "Foo"}));
} }
TEST_F(HSetFamilyTest, Issue2102) {
// Set key with element that will expire after 1s
EXPECT_EQ(CheckedInt({"HSETEX", "key", "10", "k1", "v1"}), 1);
AdvanceTime(10'000);
EXPECT_THAT(Run({"HGETALL", "key"}), RespArray(ElementsAre()));
}
} // namespace dfly } // namespace dfly