Skip to content

FUNCTION inside MULTI is queued then reported as an unknown command, for every subcommand #697

Description

@TinDang97

The gap

Every FUNCTION subcommand — valid or not — is queued by MULTI and then
answered at EXEC with ERR unknown command 'FUNCTION', with the
arguments dropped from the message. Outside a transaction the same commands
work.

Measured (moon @ c5395188, --shards 1 and --shards 4, vs redis-server 8.6.1)

Raw socket, one fresh connection per case, MULTI / <cmd> / EXEC:

command moon EXEC reply redis EXEC reply
FUNCTION LIST *1 -ERR unknown command 'FUNCTION', with args beginning with: *1 *0
FUNCTION DUMP same *1 $<payload>
FUNCTION STATS same *1 *[running_script …]
FUNCTION BOGUS same *1 -ERR unknown subcommand 'BOGUS'. Try FUNCTION HELP.

Top-level, the same binary answers correctly:

FUNCTION LIST   -> *0
FUNCTION DUMP   -> -ERR FUNCTION DUMP not supported in this release (Phase 101 limitation)
FUNCTION BOGUS  -> -ERR unknown subcommand 'BOGUS'. Try FUNCTION HELP.

FUNCTION is the ONLY container with this behaviour. The other twelve
(ACL, CLIENT, COMMAND, CONFIG, MEMORY, MODULE, OBJECT, PUBSUB,
SCRIPT, SLOWLOG, XGROUP, XINFO) all execute correctly inside MULTI.

Why it matters beyond the wrong text

The MULTI queue gate documents its safety argument as queueable iff
dispatchable
— it reads the same COMMAND_META dispatch reads, so a command
cannot become queueable-but-undispatchable. FUNCTION breaks that invariant:
COMMAND_META has it, so the gate queues it, but the EXEC executor cannot
reach the handler and falls back to the unknown-command path.

This is the moon#639 class — a family that runs through an intercept the
transaction executor cannot call — except that here the fallback lies about
the command existing
rather than failing loudly.

Consequence for moon#670

moon#670 adds queue-time rejection of unknown container subcommands. FUNCTION
has to be excluded from that gate until this is fixed, because the gate's
notion of "known subcommand" and the executor's notion disagree for this one
container. The exclusion is fenced by a test rather than left as a comment
(tests/container_subcommand_parity_670.rs).

Found

Sweeping all 14 containers × valid and bogus subcommands, top-level and inside
MULTI, against a live redis-server 8.6.1 while implementing moon#670.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions