@@ -285,9 +285,13 @@ OpResult<int64_t> OpIncrBy(const OpArgs& op_args, string_view key, int64_t incr,
285
285
auto & db_slice = op_args.GetDbSlice ();
286
286
287
287
// we avoid using AddOrFind because of skip_on_missing option for memcache.
288
- auto res = db_slice.FindMutable (op_args.db_cntx , key);
288
+ // Use type-safe FindMutable with OBJ_STRING (fixes #5316)
289
+ auto res = db_slice.FindMutable (op_args.db_cntx , key, OBJ_STRING);
290
+
291
+ if (!res) {
292
+ if (res.status () == OpStatus::WRONG_TYPE)
293
+ return res.status ();
289
294
290
- if (!IsValid (res.it )) {
291
295
if (skip_on_missing)
292
296
return OpStatus::KEY_NOTFOUND;
293
297
@@ -300,11 +304,8 @@ OpResult<int64_t> OpIncrBy(const OpArgs& op_args, string_view key, int64_t incr,
300
304
return incr;
301
305
}
302
306
303
- if (res.it ->second .ObjType () != OBJ_STRING) {
304
- return OpStatus::WRONG_TYPE;
305
- }
306
-
307
- auto opt_prev = res.it ->second .TryGetInt ();
307
+ // Type is already checked by FindMutable (OBJ_STRING)
308
+ auto opt_prev = res->it ->second .TryGetInt ();
308
309
if (!opt_prev) {
309
310
return OpStatus::INVALID_VALUE;
310
311
}
@@ -316,8 +317,8 @@ OpResult<int64_t> OpIncrBy(const OpArgs& op_args, string_view key, int64_t incr,
316
317
}
317
318
318
319
int64_t new_val = prev + incr;
319
- DCHECK (!res. it ->second .IsExternal ());
320
- res. it ->second .SetInt (new_val);
320
+ DCHECK (!res-> it ->second .IsExternal ());
321
+ res-> it ->second .SetInt (new_val);
321
322
322
323
return new_val;
323
324
}
@@ -383,20 +384,20 @@ OpResult<array<int64_t, 5>> OpThrottle(const OpArgs& op_args, const string_view
383
384
// Cost of this request
384
385
const int64_t increment_ns = emission_interval_ns * quantity; // should be nonnegative
385
386
386
- auto res = db_slice.FindMutable (op_args.db_cntx , key);
387
+ // Use type-safe FindMutable with OBJ_STRING (fixes #5316)
388
+ auto res = db_slice.FindMutable (op_args.db_cntx , key, OBJ_STRING);
387
389
const int64_t now_ns = GetCurrentTimeNs ();
388
390
389
391
int64_t tat_ns = now_ns;
390
- if (IsValid (res.it )) {
391
- if (res.it ->second .ObjType () != OBJ_STRING) {
392
- return OpStatus::WRONG_TYPE;
393
- }
394
-
395
- auto opt_prev = res.it ->second .TryGetInt ();
392
+ if (res) {
393
+ // Type is already checked by FindMutable (OBJ_STRING)
394
+ auto opt_prev = res->it ->second .TryGetInt ();
396
395
if (!opt_prev) {
397
396
return OpStatus::INVALID_VALUE;
398
397
}
399
398
tat_ns = *opt_prev;
399
+ } else if (res.status () == OpStatus::WRONG_TYPE) {
400
+ return res.status ();
400
401
}
401
402
402
403
int64_t new_tat_ns = max (tat_ns, now_ns);
@@ -458,14 +459,14 @@ OpResult<array<int64_t, 5>> OpThrottle(const OpArgs& op_args, const string_view
458
459
// break behavior because the tat_ns value will be used to check for throttling.
459
460
const int64_t new_tat_ms =
460
461
(new_tat_ns + kMilliSecondToNanoSecond - 1 ) / kMilliSecondToNanoSecond ;
461
- if (IsValid ( res. it ) ) {
462
- if (IsValid (res. exp_it )) {
463
- res. exp_it ->second = db_slice.FromAbsoluteTime (new_tat_ms);
462
+ if (res) {
463
+ if (IsValid (res-> exp_it )) {
464
+ res-> exp_it ->second = db_slice.FromAbsoluteTime (new_tat_ms);
464
465
} else {
465
- db_slice.AddExpire (op_args.db_cntx .db_index , res. it , new_tat_ms);
466
+ db_slice.AddExpire (op_args.db_cntx .db_index , res-> it , new_tat_ms);
466
467
}
467
468
468
- res. it ->second .SetInt (new_tat_ns);
469
+ res-> it ->second .SetInt (new_tat_ns);
469
470
} else {
470
471
CompactObj cobj;
471
472
cobj.SetInt (new_tat_ns);
0 commit comments