fix(nodes,scalar): fix EXPLAIN crash and wrong scan range with CASE WHEN expr#35118
fix(nodes,scalar): fix EXPLAIN crash and wrong scan range with CASE WHEN expr#35118guanshengliang merged 1 commit into3.3.6from
Conversation
…HEN subquery Three bugs triggered when a CASE WHEN expression appears as a computed column in a subquery and the outer WHERE filters on an alias of that expression (e.g. WHERE period IS NOT NULL): 1. Wrong vnode scan time range (filter.c) classifyConditionImpl traversed into the CASE WHEN subtree, found a ts column reference inside, and mis-classified the entire expression as COND_TYPE_PRIMARY_KEY. filterGetTimeRange could not extract a valid range and fell back to TSWINDOW_INITIALIZER, which was then clipped to earlyTs, producing [-29759981076409, INT64_MAX] instead of the intended window. Fix: return DEAL_RES_IGNORE_CHILD for QUERY_NODE_CASE_WHEN and mark hasOtherCol = true so the condition is treated as a non-PK filter. 2. EXPLAIN VERBOSE TRUE / ANALYZE crash - "unknown node = CaseWhen" (nodesToSQLFuncs.c) nodesNodeToSQLFormat had no cases for QUERY_NODE_WHEN_THEN or QUERY_NODE_CASE_WHEN, falling through to the default branch which returned TSDB_CODE_APP_ERROR. Fix: add serialization logic for both node types. 3. NULL datum.p segfault for ELSE NULL (nodesUtilFuncs.c) ELSE NULL produces a SValueNode with NCHAR type but datum.p == NULL. nodesGetStrValueFromNode called varDataLen(NULL), causing a segfault. Fix: add a NULL guard before the varDataLen call; callers that receive NULL now emit the SQL literal "NULL" instead of erroring. Also adds test/cases/07-DataQuerying/14-Explain/test_explain_case_when.py and registers it in test/ci/cases.task.
There was a problem hiding this comment.
Pull request overview
This PR fixes multiple issues triggered by CASE WHEN expressions used as computed columns in subqueries, especially when the outer query filters on the computed alias, improving both correctness (scan range selection) and stability (EXPLAIN / NULL handling).
Changes:
- Prevents
CASE WHENsubtrees from being misclassified as primary-key conditions during filter classification to avoid wrong vnode scan time ranges. - Adds SQL serialization support for
QUERY_NODE_CASE_WHENandQUERY_NODE_WHEN_THENto prevent EXPLAIN/ANALYZE crashes. - Guards string-value extraction for NULL-backed var-len literals and adds a regression test + CI registration.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
source/libs/scalar/src/filter.c |
Avoids traversing CASE WHEN during condition classification so time-range derivation isn’t polluted by computed expressions. |
source/libs/nodes/src/nodesToSQLFuncs.c |
Adds SQL formatting for CASE WHEN / WHEN THEN nodes and special-cases NULL value literals for formatting. |
source/libs/nodes/src/nodesUtilFuncs.c |
Adds a NULL guard before using varDataLen() on var-len value nodes. |
test/cases/07-DataQuerying/14-Explain/test_explain_case_when.py |
New regression test covering EXPLAIN crash and scan-range correctness for the reported query pattern. |
test/ci/cases.task |
Registers the new test in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Code Review
This pull request addresses issues related to CASE WHEN expressions in EXPLAIN queries and scan range optimization. Key changes include implementing SQL serialization for QUERY_NODE_WHEN_THEN and QUERY_NODE_CASE_WHEN nodes, adding safety NULL checks in node utility functions to prevent potential segmentation faults, and updating the filter classification logic to correctly handle CASE WHEN nodes as non-primary-key conditions. A new test suite has been added to verify these fixes and ensure correct scan ranges. I have no feedback to provide as the existing review comments were purely explanatory and did not identify any issues or improvement opportunities.
…HEN subquery
Three bugs triggered when a CASE WHEN expression appears as a computed column in a subquery and the outer WHERE filters on an alias of that expression (e.g. WHERE period IS NOT NULL):
Wrong vnode scan time range (filter.c) classifyConditionImpl traversed into the CASE WHEN subtree, found a ts column reference inside, and mis-classified the entire expression as COND_TYPE_PRIMARY_KEY. filterGetTimeRange could not extract a valid range and fell back to TSWINDOW_INITIALIZER, which was then clipped to earlyTs, producing [-29759981076409, INT64_MAX] instead of the intended window. Fix: return DEAL_RES_IGNORE_CHILD for QUERY_NODE_CASE_WHEN and mark hasOtherCol = true so the condition is treated as a non-PK filter.
EXPLAIN VERBOSE TRUE / ANALYZE crash - "unknown node = CaseWhen" (nodesToSQLFuncs.c) nodesNodeToSQLFormat had no cases for QUERY_NODE_WHEN_THEN or QUERY_NODE_CASE_WHEN, falling through to the default branch which returned TSDB_CODE_APP_ERROR. Fix: add serialization logic for both node types.
NULL datum.p segfault for ELSE NULL (nodesUtilFuncs.c) ELSE NULL produces a SValueNode with NCHAR type but datum.p == NULL. nodesGetStrValueFromNode called varDataLen(NULL), causing a segfault. Fix: add a NULL guard before the varDataLen call; callers that receive NULL now emit the SQL literal "NULL" instead of erroring.
Also adds test/cases/07-DataQuerying/14-Explain/test_explain_case_when.py and registers it in test/ci/cases.task.
Description
Issue(s)
Checklist
Please check the items in the checklist if applicable.