infiniflow / infiniflow/infinity
[Bug]: JSON operators -> and ->> crash both SDKs (RecursionError / unknown binary expression)
- Dominant language
- C++
- Stars
- 4.7k
- Forks
- 445
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 7
Description
## Problem
The JSON operators `->` and `->>` cannot be used from either Python SDK, even though the server registers `json_extract` / `json_extract_string` (`src/function/scalar/extract_json_impl.cpp`) and the explicit function-call form `json_extract(c3,'$.2')` works (covered by `test_select.py`).
**thrift SDK** (`python/infinity_sdk/infinity/remote_thrift/utils.py`):
- `data->'a'` (filter or output) recurses until `RecursionError`. The `JSONPath` node on the right side matches no traversal arm, and the `else` fallback does `return traverse_conditions(cons[1])` — on current sqlglot `expression[1]` builds a NEW `Bracket(this=expression.copy(), expressions=[1])` node, which matches no arm either, so the fallback calls itself forever.
- `data->>'a'` raises `InfinityException: unknown binary expression: jsonextractscalar`. sqlglot produces the key `jsonextractscalar` for `->>`, but the operator map in `python/infinity_sdk/infinity/utils.py` only has a `jsonextractstring` entry, which matches nothing.
**embedded SDK** (`python/infinity_embedded/local_infinity/utils.py` + `python/infinity_embedded/utils.py`):
- `data->'a'` / `data->>'a'` raise `unknown binary expression: jsonextract/jsonextractscalar` — the embedded operator map has no JSON entries at all, and there is no dedicated traversal arm.
## Reproduction
```python
from sqlglot import condition, parse_one
from infinity.remote_thrift.utils import traverse_conditions, parse_expr
traverse_conditions(condition("data->'a' = 'x'")) # RecursionError
traverse_conditions(condition("data->>'a' = 'x'")) # InfinityException: unknown binary expression: jsonextractscalar
parse_expr(parse_one("data->'a'")) # RecursionError
```
(sqlglot 30.18.0, current main.)
## Fix
Add a dedicated `exp.JSONExtract` / `exp.JSONExtractScalar` arm to each SDK's traversal: map `->` to `json_extract` and `->>` to `json_extract_string`, converting the `JSONPath` node to the plain string constant the server functions take (`data->'a'` becomes `json_extract(data, '$.a')`).
Contributor guide
Research direction
Start with traverse_conditions and parse_expr in python/infinity_sdk/infinity/remote_thrift/utils.py, then compare the corresponding traversal and operator-map code in python/infinity_embedded/local_infinity/utils.py and python/infinity_embedded/utils.py. Use test_select.py and the supplied reproductions to verify both JSON operators in filters and output expressions. Done means both SDKs translate -> and ->> to the registered JSON functions without recursion or unknown-expression errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100