Repository navigation
Escape backslashes in MySQL JSON path keys - #759
Merged
josevalim merged 1 commit intoOct 17, 2026
Merged
Conversation
json_extract_path keys were only escaped for the SQL string literal, so a backslash in a key reached MySQL's JSON path parser as an escape character. A key such as "a\\b" matched nothing, "a\\nb" matched the key containing a newline, and a key ending in a backslash raised a syntax error. Escape backslashes and double quotes for the JSON path first, then escape the result for the SQL string literal.
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.
The MySQL adapter's
escape_json_key/1escaped keys for the SQL string literal but not for MySQL's JSON path syntax. So after MySQL unescapes the string literal, a backslash in a key reaches the JSON path parser as an escape character. Withmeta = %{"a\\b" => 1, "a\\nb" => 2, "a\nb" => 3, "a\\" => 4}on MySQL 8.4:p.meta["a\\b"]nil1p.meta["a\\nb"]3(the value for the key that contains a newline)2p.meta["a\\"]4The fix escapes
\and"for the JSON path first, then appliesescape_string/1for the SQL literal. The output for keys containing"or'is unchanged, so the existing assertions still pass. I also ran the generated path form directly against MariaDB 11, and it resolves the same keys there.Checks run:
mix test: 707 passed (new assertions in thejson_extract_pathtest inmyxql_test.exs)mix format --check-formatted: cleanECTO_ADAPTER=myxql mix testagainst MySQL 8.4 (docker): the same 11StorageTestfailures with and without this change, because themysql/mysqldumpclient binaries aren't installed locally. Nothing else fails.TestRepoagainst MySQL 8.4, before and after the change.Not run: the earthly CI matrix, and MySQL with
NO_BACKSLASH_ESCAPES(the adapter'sescape_string/1already assumes backslash escapes are enabled).