Moritz Manner created FLINK-40901:
-------------------------------------

             Summary: JSON functions return the result of a previous row when 
JSON_TYPE or JSON_LENGTH is skipped
                 Key: FLINK-40901
                 URL: https://issues.apache.org/jira/browse/FLINK-40901
             Project: Flink
          Issue Type: Bug
          Components: Table SQL / Planner
            Reporter: Moritz Manner


JSON_TYPE and JSON_LENGTH share the parsed input if they are called on the same 
column, but only the first call in the generated code parses it. If that call 
isn't evaluated for a row, the following calls use the input that was parsed 
for an earlier row. This happens, for example, when the first call is in a CASE 
branch that isn't taken, or behind an OR that short-circuits. If there is no 
earlier row, they return NULL.

JSON_VALUE and JSON_QUERY on the same column are affected as well if a 
JSON_TYPE or JSON_LENGTH call comes before them.

The result is wrong, and there is no error.
h3. Reproduce

JSON_LENGTH returns the length of the previous row:
{code:sql}
SELECT id, CASE WHEN id > 1 THEN JSON_TYPE(j) END, JSON_LENGTH(j)
FROM (VALUES (2, '[1,2,3]'), (1, '[1]')) AS t(id, j);
{code}
||id||EXPR$1||EXPR$2||
|2|array|3|
|1|NULL|3|

The JSON_LENGTH of the second row should be 1.

JSON_TYPE returns the type of the previous row:
{code:sql}
SELECT id, CASE WHEN id > 1 THEN JSON_LENGTH(j) END, JSON_TYPE(j)
FROM (VALUES (2, '[1,2,3]'), (1, '{"a":1}')) AS t(id, j);
{code}
||id||EXPR$1||EXPR$2||
|2|3|array|
|1|NULL|array|

The JSON_TYPE of the second row should be object.

JSON_VALUE returns the value of the previous row:
{code:sql}
SELECT id, CASE WHEN id > 1 THEN JSON_TYPE(j) END, JSON_VALUE(j, '$.a')
FROM (VALUES (2, '{"a":"x"}'), (1, '{"a":"y"}')) AS t(id, j);
{code}
||id||EXPR$1||EXPR$2||
|2|object|x|
|1|NULL|x|

The JSON_VALUE of the second row should be y.

JSON_QUERY returns the value of the previous row:
{code:sql}
SELECT id, CASE WHEN id > 1 THEN JSON_TYPE(j) END, JSON_QUERY(j, '$.a')
FROM (VALUES (2, '{"a":[1]}'), (1, '{"a":[2]}')) AS t(id, j);
{code}
||id||EXPR$1||EXPR$2||
|2|object|[1]|
|1|NULL|[1]|

The JSON_QUERY of the second row should be [2].

The same happens in a WHERE clause:
{code:sql}
SELECT id, JSON_LENGTH(j)
FROM (VALUES (2, '[1,2,3]'), (1, '[1]')) AS t(id, j)
WHERE id > 1 OR JSON_TYPE(j) = 'array';
{code}
This returns (2, NULL) and (1, 1). It should return (2, 3) and (1, 1).
h3. Notes
 * Only the first JSON function call on a column decides this. If it is 
JSON_VALUE or JSON_QUERY, the results are correct, even if that call is skipped.
 * If the call outside the CASE comes before the CASE, the result is correct.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to