From 26a72fa89c8da17c6529a645853d6559e5fdcb70 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 1362b5f9dd..9a53e6b4d1 100644 --- a/src/db.c +++ b/src/db.c @@ -125,7 +125,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} {