fix: cast to json unknown 65535 error and add ut cases#35073
fix: cast to json unknown 65535 error and add ut cases#35073guanshengliang merged 4 commits intomainfrom
Conversation
…nstant arg returns invalid input - builtins.c: reject CAST(expr AS JSON) in translateCast() with TSDB_CODE_CAST_TO_JSON_NOT_ALLOWED instead of silently passing validation and failing at execution with TSDB_CODE_FAILED (-1) - scalar.c: add QUERY_NODE_LEFT_VALUE case in sclGetNodeType() so rewritten constant operands (ASSIGN operator left side) resolve their type from ctx->type.opResType instead of hitting the 'unsupported node type' fallthrough (error 0x070F invalid input) - executorInt.c: create dummy column for the first arg of indefinite- rows functions when it is a constant, preventing NULL pData[0] - test_fun_sca_cast.py: add do_cast_to_json_invalid() covering all 19 sql-fuzzing repro queries for the CAST-to-JSON bug Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add missing node type cases to sclGetNodeType() that were hit after ed9de01 changed the fallthrough from silent type=-1 to hard error: 1. QUERY_NODE_LEFT_VALUE (27): return ctx->type.opResType, used when the planner rewrites constants into ASSIGN(LEFT_VALUE, VALUE) operators for scalarSup pre-processing (e.g. mavg(2.0, 3)) 2. QUERY_NODE_REMOTE_VALUE_LIST (61): read resType from SExprNode, used when IN subquery RHS is a remote value list node 3. QUERY_NODE_REMOTE_VALUE / QUERY_NODE_REMOTE_ZERO_ROWS / QUERY_NODE_REMOTE_ROW: read resType from embedded SValueNode, defensive coverage for other remote node types Also extend doSetInputDataBlock() dummy-column creation to cover the first constant argument of indefinite-rows functions (mavg, csum, diff) so pInput->pData[0] is not NULL at function execution time. Fixes: select distinct t1,'abc',tbname from st1 -> invalid input Fixes: 1 in (select 1 from st1) -> invalid input Fixes: mavg(cast(2 as float), 3) -> invalid input Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- sclfunc.c: return TSDB_CODE_SCALAR_CONVERT_ERROR in castFunction default branch instead of TSDB_CODE_FAILED(-1) to avoid "Unknown error 65535" - scalarTests.cpp: add unit test castToJsonShouldReturnConvertError verifying castFunction(INT->JSON) returns TSDB_CODE_SCALAR_CONVERT_ERROR - test_fun_sca_cast.py: add do_cast_to_json_unknown_error_regression() with 23 sqlsmith repro queries, assert no "Unknown error 65535" in error message
There was a problem hiding this comment.
Code Review
This pull request prevents 'Unknown error 65535' by explicitly disallowing casts to JSON and improving error code propagation in scalar functions. It also updates the executor to correctly expand constant arguments for indefinite-rows functions and refines node type resolution for row-count placeholders. Feedback was provided to include a NULL check for expression pointers in the executor to improve robustness against potential crashes.
I am having trouble creating individual review comments. Click here to see my feedback.
source/libs/executor/src/executorInt.c (383-387)
Accessing pOneExpr->pExpr without a NULL check could lead to a crash if the expression node is not initialized. While it is generally expected to be valid in the executor context, adding a safety check before accessing nodeType and _function is a best practice for robustness.
if (!needDummyCol && j == 0 && pOneExpr->pExpr != NULL &&
pOneExpr->pExpr->nodeType == QUERY_NODE_FUNCTION &&
fmIsIndefiniteRowsFunc(pOneExpr->pExpr->_function.functionId)) {
needDummyCol = true;
}There was a problem hiding this comment.
Pull request overview
Fixes the “CAST(... AS JSON) -> Unknown error 65535” behavior by returning a deterministic, user-facing error during translation/runtime, and adds regression coverage in both Python system tests and C++ scalar unit tests. Also includes small scalar/executor adjustments related to constant/placeholder node typing and constant-arg handling for indefinite-rows functions.
Changes:
- Reject
CAST(expr AS JSON)during function translation and avoid propagatingTSDB_CODE_FAILEDas “Unknown error 65535”. - Make
castFunction()returnTSDB_CODE_SCALAR_CONVERT_ERRORfor unsupported output types instead ofTSDB_CODE_FAILED. - Add regression tests (Python SQLSmith repro list + C++ unit test) and adjust scalar/executor handling for LEFT_VALUE typing and constant expansion for indefinite-rows functions.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/cases/11-Functions/01-Scalar/test_fun_sca_cast.py | Adds SQLSmith-style regression coverage for CAST-to-JSON error behavior. |
| source/libs/scalar/test/scalar/scalarTests.cpp | Adds a unit test asserting castFunction() returns TSDB_CODE_SCALAR_CONVERT_ERROR when output type is JSON. |
| source/libs/scalar/src/sclfunc.c | Changes default cast output-type handling to return TSDB_CODE_SCALAR_CONVERT_ERROR. |
| source/libs/scalar/src/scalar.c | Adds explicit type resolution for QUERY_NODE_LEFT_VALUE using operator result type. |
| source/libs/function/src/builtins.c | Rejects CAST(... AS JSON) at translation time with a descriptive message. |
| source/libs/executor/src/executorInt.c | Refines dummy-column creation logic for constant parameters, especially for indefinite-rows functions’ first argument. |
Comments suppressed due to low confidence (1)
test/cases/11-Functions/01-Scalar/test_fun_sca_cast.py:1524
do_cast_to_json_invalid()callstdSql.error(...)but never inspects the returnederror_info, so the test will still pass if the server returns the exact regression you're trying to prevent ("Unknown error 65535"). Capture the returned error string (or passexpectErrInfo/expectedErrno) and assert it does not contain "Unknown error 65535" (and ideally matches the expected CAST-to-JSON rejection message).
# All of the following must return a proper error (not Unknown error 65535)
tdSql.error("select n, si from t3 where c1 > 2.97 order by ((-ubi) % f) % (-22) asc nulls last, cast(ti as json) desc nulls last limit 12 offset 33;")
tdSql.error("select bi, ubi, ubi from t2 order by cast(-pow(usi, floor(pow(id, f))) as json) desc nulls last;")
tdSql.error("select c1 from t1 order by +(-(-f)) asc nulls last, cast(position('s_431' in upper(a)) as json) asc nulls last limit 50 offset 43;")
tdSql.error("select usi, vb from t1 where usi > 6 order by cast(v as json) asc nulls last limit 5 offset 45;")
tdSql.error("select v from t2 order by cast(pow(abs(bi), d) & ti as json) asc nulls last;")
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Description
Issue(s)
Checklist
Please check the items in the checklist if applicable.