mrhhsg opened a new pull request, #69170:
URL: https://github.com/apache/doris/pull/69170
### What problem does this PR solve?
Issue Number: None
Problem Summary:
`JSON_SEARCH` builds the returned JSON path by concatenating each object key
as a bare member leg (`.key`), only double-quoting the leg when the key
contains whitespace. When the key itself contains a character that
`JsonbPath`'s parser treats as structural when unquoted — `.`, `[`, a leading
`*`, or an empty key — the emitted path does not parse back into the same
single leg, so feeding the result into `JSON_EXTRACT`/`JSON_SEARCH` again
resolves to a different value (or fails to parse).
For example:
```sql
JSON_SEARCH('{"a.b":"hit","a":{"b":"miss"}}', 'one', 'hit')
-- returns $.a.b, which JSON_EXTRACT parses as a -> b and resolves to "miss"
instead of "hit"
```
The fix makes `leg_info::to_string` double-quote a member leg whenever the
unquoted form would not read back as the same leg (mirroring `JsonbPath`'s own
unquoted-leg grammar: empty key, leading `*`, or containing
whitespace/`.`/`[`), and adds a few supporting changes so the rest of the path
code treats a quoted literal key consistently with a parsed wildcard:
- A new `leg_info::is_wildcard` flag, set only by the parser for an unquoted
`*` / `[*]` leg, distinguishes a real wildcard from the literal key `"*"`.
`to_string` and `findValue` both switch to this flag instead of comparing leg
bytes, since a quoted `"*"` leg has the same bytes as a wildcard leg.
- `$.""` (an explicit empty key) is accepted by the parser and can be looked
up; `ObjectVal::search` no longer treats an empty key length as "not found",
and the internal lookup distinguishes an explicit empty key from an object
entry that is stored by numeric key id (which also has key length 0).
- `JsonbValue::contains` looks up a key-id-encoded right-hand key by id
instead of by name, for the same reason.
- `JSON_SET`/`JSON_INSERT` no longer write a member-style leg into an array
(matching MySQL); previously the leg's default array index (0) would overwrite
or append to the array.
- A pre-existing formatting issue where a wildcard array leg (`[*]`) was
printed back as `[0]` is fixed alongside, since it shares the same root cause
(no explicit wildcard marker).
### Release note
`JSON_SEARCH` now quotes a returned path segment whenever the key contains
`.`, `[`, starts with `*`, or is empty, so the result can be parsed again by
`JSON_EXTRACT`/`JSON_SEARCH`/`JSON_SET`/etc. As a side effect, `$.""` is now a
valid path for an explicit empty key, a quoted `"*"` key is treated as a
literal key instead of a wildcard, and `JSON_SET`/`JSON_INSERT` no longer
modify an array when the path's last segment is a member (non-array-index) leg.
### Check List (For Author)
- Test
- [x] Unit Test
- [x] Regression test
- Behavior changed:
- [x] Yes. See Release note above.
- Does this need documentation?
- [ ] No.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]