From 4cfa6fbef6458bb3594ec58eb534e8b76c9e77c2 Mon Sep 17 00:00:00 2001 From: Simon Baatz Date: Tue, 31 Dec 2024 13:51:44 +0100 Subject: [PATCH] Use the correct command proc for the LOOKUP_NOTOUCH exception in lookupKey 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. 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 --- 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 e31d7e7f7f..99b5a9e33f 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)) { /* Shared objects can't be stored in the database. */ diff --git a/tests/unit/introspection-2.tcl b/tests/unit/introspection-2.tcl index b8f4e0aed4..301c86937b 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} {