Pre-Reqs in SQL JSON Functions before improving NULL Support#204
Conversation
59d55a6 to
6c2dc35
Compare
…IG_DECIMAL li-pinot's BaseTransformFunction.init 3-arg form takes QueryContext, not the boolean nullHandlingEnabled used by upstream. Apply the corresponding signature change in JsonExtractScalarTransformFunction. Field access via the inherited _nullHandlingEnabled is unchanged (set by super.init from queryContext.isNullHandlingEnabled()). li-pinot does not yet have MV BIG_DECIMAL support (transformToBigDecimalValuesMV / initBigDecimalValuesMV / _bigDecimalValuesMV — added upstream by apache/pinot#18326 which is not in this prereq chain). Drop the BIG_DECIMAL_ARRAY case from this transform's MV path and from the supported-types error message and Javadoc. SV BIG_DECIMAL handling is unaffected. Update tests accordingly.
|
This is now ready for review. Once merged, #205 should be rebased on this and can be reviewed. |
UOETianleZhang
left a comment
There was a problem hiding this comment.
Seems we are mostly cherry-picking from OSS. The only extra change 4ad3802 is minior and it LGTM.
There is an issue in OSS commits and I have left one comment on it. It is non-blocking, we can address it in a follow up PR.
| /// a resolved array still throw. | ||
| /// | ||
| /// **Supported `resultsType`:** `INT`, `LONG`, `FLOAT`, `DOUBLE`, `BIG_DECIMAL`, `BOOLEAN`, `TIMESTAMP`, | ||
| /// `STRING`, `JSON`, `BYTES`, plus `_ARRAY` variants of `INT` / `LONG` / `FLOAT` / `DOUBLE` / |
There was a problem hiding this comment.
We are mentioning BYTES result type is supported but it will throw exception at runtime. This class never overrides transformToBytesValuesSV so it will call parent class's method BaseTransformFunction.transformToBytesValuesSV. In which an exception will be raised at runtime (BYTES has stored type BYTES, so it falls through to the base class):
switch (resultDataType.getStoredType()) {
case BIG_DECIMAL: ...
case STRING: ...
case UNKNOWN: ...
default:
throw new IllegalStateException("Cannot read SV " + resultDataType + " as BYTES");
}
To fix it, we cab either implement transformToBytesValuesSV, or drop BYTES from the supported-types.
I am aware this issue is inherited from OSS, so we can also resolve it in a follow up PR.
There was a problem hiding this comment.
Yes, 80% code is a cherry-pick. It's needed for a capability I am building in PR #205
Good catch. I will remove BYTES call out from supported types. Thanks for the review.
The prior WIP commit narrowed the per-row catch to PathNotFoundException +
InvalidJsonException to surface non-JSON input as a hard error. But jayway
throws a third, distinct exception for a null/empty JSON cell —
IllegalArgumentException("json can not be null") from ParseContextImpl.parse —
which neither arm caught. That exception escaped and broke the 14
testDefaultValue cases from #204 (null JSON cell + a configured default must
return the default, not throw).
Restore the broad catch for everything that represents a missing value, and
peel off only genuinely malformed input:
- InvalidJsonException -> throw IllegalArgumentException("...not valid
JSON..."), regardless of null handling
(non-JSON column is a schema modeling error).
- everything else (null/empty input, missing path) -> swallowed; result stays
null and the existing null-handling / default
cascade decides (preserves #204 and #205).
Add a boundary test (testNonJsonInputThrowsEvenWithDefaultValue) proving a
configured default does not mask non-JSON input — the parse failure is thrown
before the default cascade is reached.
Verified locally: JsonExtractScalarTransformFunctionTest 145/145,
QueryRunnerTest 131/131 (case #12 throws the expected message), spotless +
checkstyle clean on pinot-core and pinot-query-runtime.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
I am working on improving NULL Support in JSON. I started that work directly upstream and it was based on top off some orthogonal refactoring in the JSON functions which is not available in the fork. The refactoring is important and I am porting it first to fork before creating the actual NULL feature work in JSON.
Capabilities added in this PR
Commits (in order)
f2153a1382JsonExtractScalarTransformFunctionwith default value supportc297fbec3binit(..., boolean nullHandlingEnabled))5cb954d578JsonExtractScalarTransformFunction: type coercion,BIG_DECIMAL_ARRAY, guards (introduces_dataType/_storedTypefields + per-type literal extraction)