[
https://issues.apache.org/jira/browse/FLINK-41298?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
ASF GitHub Bot updated FLINK-41298:
-----------------------------------
Labels: pull-request-available (was: )
> PARSE_JSON, TRY_PARSE_JSON and the raw format drop content after the first
> JSON value
> -------------------------------------------------------------------------------------
>
> Key: FLINK-41298
> URL: https://issues.apache.org/jira/browse/FLINK-41298
> Project: Flink
> Issue Type: Bug
> Components: API / Core, Table SQL / Runtime
> Affects Versions: 2.1.0, 2.2.0, 2.3.0
> Reporter: Ramin Gharib
> Assignee: Ramin Gharib
> Priority: Major
> Labels: pull-request-available
>
> {{PARSE_JSON}} reads the first JSON value in its input and stops. It never
> checks that the input ends there, so anything after that value is dropped
> without an error. Two JSON documents in one string come back as the first
> one, and the second is lost.
> {noformat}
> SELECT JSON_STRING(PARSE_JSON('{"a":1} xyz')); -- {"a":1}, expected an
> error
> SELECT JSON_STRING(PARSE_JSON('[1]]')); -- [1], expected an error
> SELECT JSON_STRING(PARSE_JSON('{"a":1}{"a":2}')); -- {"a":1}, expected an
> error
> SELECT JSON_STRING(TRY_PARSE_JSON('{"a":1} xyz')); -- {"a":1}, expected NULL
> {noformat}
> Output of {{BinaryVariantInternalBuilder.parseJson(input, false)}} on the
> 2.3.0 jars:
> {noformat}
> input result
> {"a":1} xyz {"a":1}
> [1]] [1]
> {"a":1}{"a":2} {"a":1}
> {"a":1}\n{"a":2} {"a":1}
> 1 2 1
> hello JsonParseException: Unrecognized token 'hello'
> {noformat}
> Two entry points on master reach this code:
> ||Entry point||Builder method||
> |{{PARSE_JSON}}, {{TRY_PARSE_JSON}}|{{parseJson(byte[], boolean)}}, through
> {{SqlJsonUtils.parseJsonToVariant}}|
> |{{raw}} format, VARIANT column|{{parseJson(String, boolean)}}, in
> {{RawFormatDeserializationSchema}}|
> Both overloads end the same way:
> {code:java}
> try (JsonParser parser = JSON_FACTORY.createParser(bytes)) {
> parser.nextToken();
> return parseJson(parser, allowDuplicateKeys); // returns after one value
> }
> {code}
> The same class already rejects content glued to a number, with "Unexpected
> content after the JSON number". It does not check what follows the whole
> value.
> *Proposal*
> In {{parseJson(String, boolean)}} and {{parseJson(byte[], boolean)}}, call
> {{parser.nextToken()}} once more after the value is built, and throw a
> {{JsonParseException}} if it is not null. Then {{PARSE_JSON}} fails,
> {{TRY_PARSE_JSON}} returns NULL, and the {{raw}} format reports a
> deserialization error for the record. Whitespace after the value stays
> allowed, because Jackson skips it.
> {{parseJson(JsonParser, boolean)}} stays as it is. Its caller owns the parser
> and decides what may follow.
> *Relation to FLINK-40225*
> FLINK-40225 asked for the same check in {{IS JSON}}, {{JSON_VALUE}} and the
> other JSON functions. It was closed as Won't Fix: it breaks running jobs, and
> lenient parsing is the default in Jackson and Spark. This case differs in two
> ways:
> # {{PARSE_JSON}} stores what it parsed. The dropped text is lost data, not a
> looser validity check. A {{raw}} record that holds newline-delimited JSON
> documents keeps only the first one.
> # The {{raw}} format's VARIANT support is new in 2.4.0, which is not released
> yet. Making it strict now breaks no running job.
> *Open question*
> {{PARSE_JSON}} has been out since 2.1.0, so rejecting trailing content turns
> input that parses today into an error. Should that part go to the dev@ list
> first, as FLINK-40225 suggests, while the {{raw}} format gets the check for
> 2.4.0?
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)