fix(plugin-redis): the Redis, Explain and connection defects found alongside #3036 - #3039
Merged
Merged
Conversation
…ading the session status
…r holding only whitespace
…nd keep curated ones a plugin leaves empty
…d refuse analyze without one
…ng db4 and over a tunnel
…of doubling the container name
…e an open MULTI block
…d with no write flag
…ep the post-connect switch
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3038. Refs #3036.
#3038 fixed the reported bug and the defects found alongside it. Its report listed more that were real but out of its scope; this PR fixes all of them, plus what turned up while fixing those.
Redis on the Mac
fix(connections): open the Redis database a connection names…db4spelling iOS and the plugin accept. A connection synced from iPhone with databasedb4openeddb4there anddb0on the Mac. The driver config, the post-connect step, the toolbar, the form and the URL export now share one resolution: the Database Index field, then the value saved before that field existed, then the database name. A Cluster connection always opens ondb0, even when a Database Index field left over from a Standalone setup still holds another value. Over an SSH tunnel the tunnel forces Standalone, so the index is resolved before that happens. The driver opens that index at connect. A second window for a connection shows the database the live session is on, not the configured one.fix(connections): refuse a Redis URL whose path is not a database indexredis://host/-1was accepted and failed at connect./1.5and/abcwere dropped without a word, sodb0opened.redis+ssh://…/3never read the index at all. All of these now fail with the existing "is not a Redis database index" message.fix(plugin-redis): keep every argument of a Redis command the parser modelsSCAN … TYPE hashlisted every type,CONFIG GET a breturned one row, andPING helloanswered 1.GET a bran asGET a. ValidXGROUP HELP,OBJECT HELPandCONFIG RESETSTATwere refused. A command with arguments its result view does not model is now sent exactly as typed.test(plugin-redis): test the real Redis command parser…,refactor(plugin-redis): render Redis replies from a type the tests compilefix(sidebar): load the Redis key tree from its own databaseKEYTREEwith no database, so after aSELECTtyped in the editor it listed, and opened keys from, the editor's database. It now sendsKEYTREE DB n, and a key opened from the tree reads throughDB n <command>, so the editor's session stays where it was.fix(plugin-redis): read the server's subcommand routing tips…COMMANDreply parser put the container name in front of subcommand names that already carried it (config|config|set). Every subcommand tip was therefore lost, andFUNCTION LOAD,ACL SETUSERandCONFIG REWRITEreached one primary out of three.fix(plugin-redis): report a split Redis Cluster write that only some shards appliedDELor a fanned-outFLUSHDBthat one shard refused reported only the refusal. Redis cannot undo the part that already ran, so the error now names the keys, or forFLUSHDBthe nodes, that were already changed. That includes fan-outs with nowriteflag that still change every node, such asCONFIG SETandACL SETUSER.feat(plugin-redis): browse numbered databases on a Valkey 9 clustercluster-databasesabove 1 listed onlydb0, andSELECT 3was refused locally. The count is learned once per primary at connect. A cluster cannot wrap a grid save inMULTI, so there each write carries its database asDB <n> <command>and a failed save cannot strand the session. The editor accepts the same syntax, and the Safe Mode classifier reads past it, soDB 0 FLUSHDBstill asks for confirmation. ADB ncommand on a primary holding the user's openMULTIblock is refused rather than queued into the block on the home database.fix(editor): classify a quoted Redis command as the command the driver runsredis-clidoes."FLUSHALL",'FLUSHDB' ASYNCand"\x46LUSHALL"all passed as ordinary writes. The classifier now uses the driver's own codec, which is compiled into the app along withRedisDatabaseIndex.swift, and the key tree quotes keys with it too.fix(plugin-redis): match a Redis namespace literally when counting its keysbuildCountQueryput the namespace in quotes without escaping it. No driver path passes a non-empty namespace today, so this could not be reached from the app.Explain
fix(plugins): give Redshift and Teradata their own Explain variants…EXPLAIN (FORMAT JSON)andEXPLAIN (ANALYZE, FORMAT JSON), which Redshift rejects as syntax errors. It now offersEXPLAINandEXPLAIN VERBOSEas text. The plugin registry now keeps a curated variant list when a plugin declares none. #3038 had given DuckDB an empty list, which took Explain away from DuckDB the moment its plugin loaded. Teradata gets itsEXPLAINrequest modifier.fix(mcp): send explain_query only a variant the database declares…explain_querymade upEXPLAINfor engines with no variant, so Redis was sentEXPLAIN GET k.analyze: trueon an engine without an ANALYZE variant quietly returned an estimate. Both are now refused, as isanalyze: truewith an explicit variant that only estimates. Each error names the variants to use instead. A statement that already starts withEXPLAINstill passes through verbatim.fix(editor): dim Run and Explain Query in the Query menu…refactor(coordinator): remove the empty driver branches…if let driver = … {}blocks and their unreachableelsebranches.iPhone and iPad
fix(ios): report a Redis command the server refuses…fix(ios): list each Redis key once…SCANmay return a key twice, and the list showed it twice.fix(ios): browse Redis keys with Redis commands instead of SQLSELECT * FROM key LIMIT …, which Redis rejects withERR wrong number of arguments for 'select' command. A key now opens by type: a string's value, a hash's fields, a list's elements, a set's members, a sorted set's members and scores, or a stream's entries.fix(ios): report a Redis ACL refusal as a permission error…NOPERMread as Authentication Failed, with a hint to check the username and password.Connection form and tooling
fix(connection-form): accept only a whole number in a number field-,.and non-ASCII digits, and nothing stopped Save. Neither value ever worked at connect.fix(ci): read wrapped and escaped plugin strings into the app cataloglocalization.py pluginsmissed anyString(localized:)call wrapped afterString(, and any literal containing\", so 52 plugin strings never reached the catalog. Most of them are AWS SSO and credential_process errors.The Repo Hygiene failure linked on #3038 was already fixed there by
5b54e3c98.Verification
five:xread as a query parameter. The key is now always quoted, and both suites then passed (36 of 36 and 25 of 25).WorkspaceRailCellRenderingTests, an offscreen pixel test in a file this branch does not touch. It was only in the run because it contains the wordisRedish.AllPlugins).SCAN 0 TYPE hashreturns two keys where it returned all seven.CONFIG GET maxmemory maxclientsreturns two rows where it returned one.XGROUP HELPandOBJECT HELPreach the server instead of being refused.SELECT 5,KEYTREE DB 0lists db0's seven keys, andDBSIZEstill reports db5.cluster-databases 16:FUNCTION LOADandACL SETUSERreach 3 of 3 primaries where they reached 1.DELthat one shard refused namesallowed:1as already deleted.db0throughdb15, and a db3 grid save goes out asDB 3 SET …and leaves the session on db0.SELECT 3with nothing sent.scripts/check-redis-command-routing.shcompared 151 commands against Redis 8.10.1 and Valkey 9.1.2 and found 0 mismatches.verify.sh docs,localization.py pluginsandcheck-ios-shared-isolation.pyall pass.code-reviewskill reviewed the whole diff and returned 15 findings."FLUSHALL"passing Safe Mode;DB nwrite queued into an openMULTIblock;CONFIG SETorACL SETUSERfan-out going unreported;explain_queryacceptinganalyzewith a variant that only estimates;Not covered
docs/ioshas no Redis screenshot.INSERTfor a Redis connection.KEYS,LRANGE,SMEMBERSandMGETresults read wrong.String(cString:)in the iOS reply parser stops a binary value at its first NUL byte.FLUSHDBtruncate still refuses a database other than the session's, even thoughDB <n> FLUSHDBcould now handle it.MULTIopens on one primary while the other shards keep running.CONFIGstays ondb0even whencluster-databasesis above 1. This is documented;INFO keyspacecould stand in for it.CONFIG GET cluster-databasesat connect andINFO keyspacefor each count one primary at a time, not in parallel.;after\"inside a quoted argument may split one command in two.