infiniflow / infiniflow/infinity

[Bug]: JSON operators -> and ->> crash both SDKs (RecursionError / unknown binary expression)

Open
#3,463 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.