From d6e9ff1f856378af937c89ebb97501287910fb5e Mon Sep 17 00:00:00 2001 From: gmbnomis Date: Fri, 3 Jan 2025 02:41:15 +0100 Subject: [PATCH] Use the correct command proc for the LOOKUP_NOTOUCH exception in lookupKey (#1499) When looking up a key in no-touch mode, `LOOKUP_NOTOUCH` is set to avoid updating the last access time in `lookupKey`. An exception must be made for the `TOUCH` command which must always update the key. When called from a script, `server.executing_client` will point to the `TOUCH` command, while `server.current_client` will point to e.g. an `EVAL` command. So, we must use the former to find out the currently executing command if defined. This fix addresses the issue where TOUCH wasn't updating key access times when called from scripts like EVAL. Fixes #1498 Signed-off-by: Simon Baatz Co-authored-by: Binbin --- src/db.c | 2 +- tests/unit/introspection-2.tcl | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/db.c b/src/db.c index ceb3105f9..441982bdc 100644 --- a/src/db.c +++ b/src/db.c @@ -124,7 +124,7 @@ robj *lookupKey(serverDb *db, robj *key, int flags) { * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */ if (server.current_client && server.current_client->flag.no_touch && - server.current_client->cmd->proc != touchCommand) + server.executing_client->cmd->proc != touchCommand) flags |= LOOKUP_NOTOUCH; if (!hasActiveChildProcess() && !(flags & LOOKUP_NOTOUCH)) { if (!canUseSharedObject() && val->refcount == OBJ_SHARED_REFCOUNT) { diff --git a/tests/unit/introspection-2.tcl b/tests/unit/introspection-2.tcl index b8f4e0aed..301c86937 100644 --- a/tests/unit/introspection-2.tcl +++ b/tests/unit/introspection-2.tcl @@ -30,11 +30,24 @@ start_server {tags {"introspection"}} { assert {[r object idletime foo] >= 2} } - test {TOUCH alters the last access time of a key} { + proc test_touch_alters_access_time {} { r set foo bar + r set script_foo bar after 3000 r touch foo + r eval {redis.call('touch', KEYS[1])} 1 script_foo assert {[r object idletime foo] < 2} + assert {[r object idletime script_foo] < 2} + } + + test {TOUCH alters the last access time of a key} { + test_touch_alters_access_time + } + + test {TOUCH alters the last access time of a key in no-touch mode} { + r client no-touch on + test_touch_alters_access_time + r client no-touch off } test {Operations in no-touch mode do not alter the last access time of a key} {