Conversation
There was a problem hiding this comment.
Code Review
This pull request implements the FILL clause for EXTERNAL_WINDOW queries, supporting modes such as NULL, VALUE, PREV, and NEXT. The implementation covers documentation, grammar updates, plan generation, and executor logic. Review feedback points out a potential crash in extWinAppendAggFilledRow due to uninitialized pointer usage during error jumps and identifies redundant fill mode checks when processing adjacent rows.
There was a problem hiding this comment.
Pull request overview
This PR adds FILL clause support for EXTERNAL_WINDOW queries, plumbing fill mode/values through the parser → planner → physical-plan serialization → executor, and adding regression tests + documentation updates around the supported/unsupported fill matrix.
Changes:
- Extend SQL grammar + translation to accept
EXTERNAL_WINDOW(... fill(...)), validate unsupported modes (LINEAR/NEAR/SURROUND), and enforce “aggregate-only” fill usage. - Carry external-window fill metadata through logical/physical planning, cloning, TLV/JSON encode/decode, and node destruction.
- Implement executor-side external-window fill behaviors (NONE/NULL/NULL_F/VALUE/VALUE_F/PREV/NEXT), and add CI coverage + docs.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| test/ci/cases.task | Adds CI execution entry for new external-window fill test module |
| test/cases/13-TimeSeriesExt/08-ExternalWindow/test_external.py | Updates existing regression to reflect fill now supported; adds fill support matrix assertions + negatives |
| test/cases/13-TimeSeriesExt/08-ExternalWindow/test_external_fill.py | New comprehensive regression suite for external-window fill (and related interval-fill comparisons) |
| source/libs/planner/src/planPhysiCreater.c | Propagates external fill info into physical external-window plan nodes; maps fill expressions to slotted targets |
| source/libs/planner/src/planLogicCreater.c | Builds external-window fill expr list from projection; rewrites it post-select rewrite; adjusts HAVING placement for interval+fill |
| source/libs/parser/src/parTranslater.c | Enables fill handling for external window, adds aggregate-only restriction, and routes fill-values validation to external-window fill nodes |
| source/libs/parser/src/parAstCreater.c | Ensures external-window fill node uses the correct primary-key timestamp column (pWStartTs) |
| source/libs/parser/inc/sql.y | Extends external_window_fill_opt grammar to support value/position fill modes |
| source/libs/nodes/src/nodesUtilFuncs.c | Adds destruction for embedded external fill info in logic/physical nodes |
| source/libs/nodes/src/nodesMsgFuncs.c | Adds TLV serialization fields for external-window fill mode/exprs/values |
| source/libs/nodes/src/nodesCodeFuncs.c | Adds JSON serialization fields for external-window fill mode/exprs/values |
| source/libs/nodes/src/nodesCloneFuncs.c | Adds clone support for external-window fill fields (logic + physical nodes) |
| include/libs/nodes/plannodes.h | Introduces SExtWindowFillInfo embedded into window logic/physical plan nodes |
| source/libs/executor/src/externalwindowoperator.c | Implements executor-side external-window fill behavior and filter integration |
| source/libs/executor/src/filloperator.c | Minor formatting-only change |
| docs/zh/05-basic/03-query.md | Documents external-window fill modes and behavior |
| docs/en/05-basic/03-query.md | Documents external-window fill modes and behavior |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Support FILL clause in external_window queries with options: NONE/NULL/PREV/NEXT/VALUE/NULL_F/VALUE_F - Support FILL clause combined with HAVING clause - Reject unsupported fill modes: LINEAR/NEAR/SURROUND - Add CI test cases (test_external_fill.py) for coverage
2b2feb3 to
836797f
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 20 out of 21 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (4)
docs/zh/14-reference/03-taos-sql/24-distinguished.md:56
- The window_clause grammar snippet lists
EXTERNAL_WINDOW ((subquery) window_alias)twice (once with[fill_clause]and again without). This duplication is confusing and should be reduced to a single entry reflecting the supported syntax (with optional[fill_clause]).
```sql
window_clause: {
SESSION(ts_col, tol_val)
| STATE_WINDOW(expr[, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)]
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [fill_clause]
| EXTERNAL_WINDOW ((subquery) window_alias) [fill_clause]
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
| COUNT_WINDOW(count_val[, sliding_val][, col_name ...])
| EXTERNAL_WINDOW ((subquery) window_alias)
}
docs/en/14-reference/03-taos-sql/24-distinguished.md:54
- The window_clause grammar snippet lists
EXTERNAL_WINDOW ((subquery) window_alias)twice (once with[fill_clause]and again without). Please remove the redundant entry so the documentation shows a single canonical syntax.
```sql
window_clause: {
SESSION(ts_col, tol_val)
| STATE_WINDOW(expr [, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)]
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [fill_clause]
| EXTERNAL_WINDOW ((subquery) window_alias) [fill_clause]
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
| COUNT_WINDOW(count_val[, sliding_val][, col_name ...])
| EXTERNAL_WINDOW ((subquery) window_alias)
}
docs/zh/14-reference/03-taos-sql/20-select.md:65
- The
window_clausesyntax block includesEXTERNAL_WINDOW ((subquery) window_alias)twice (with and without[fill_clause]). Keeping both makes the grammar ambiguous; it should be a single production with optional[fill_clause].
window_clause: {
SESSION(ts_col, tol_val)
| STATE_WINDOW(expr [, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)]
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [fill_clause]
| EXTERNAL_WINDOW ((subquery) window_alias) [fill_clause]
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
| COUNT_WINDOW(count_val[, sliding_val][, col_name ...])
| EXTERNAL_WINDOW ((subquery) window_alias)
}
docs/en/14-reference/03-taos-sql/20-select.md:63
- The
window_clausesyntax block contains duplicateEXTERNAL_WINDOW ((subquery) window_alias)entries (with and without[fill_clause]). Please remove the redundant line and keep one canonical syntax with optional[fill_clause].
window_clause: {
SESSION(ts_col, tol_val)
| STATE_WINDOW(expr [, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)]
| INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [WATERMARK(watermark_val)] [fill_clause]
| EXTERNAL_WINDOW ((subquery) window_alias) [fill_clause]
| EVENT_WINDOW START WITH start_trigger_condition END WITH end_trigger_condition [TRUE_FOR(true_for_expr)]
| COUNT_WINDOW(count_val[, sliding_val][, col_name ...])
| EXTERNAL_WINDOW ((subquery) window_alias)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #include "stream.h" | ||
| #include "filter.h" | ||
| #include "cmdnodes.h" | ||
| #include "../../function/inc/functionResInfoInt.h" |
| if (pFunc->funcType == FUNCTION_TYPE_GROUP_KEY || | ||
| pFunc->funcType == FUNCTION_TYPE_GROUP_CONST_VALUE) continue; | ||
| SNode* pClone = NULL; | ||
| PLAN_ERR_RET(nodesCloneNode(pExpr, &pClone)); |
| } | ||
| ++idx; | ||
| } | ||
| if (pSlotted != NULL) { |
| } | ||
|
|
||
| if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) { | ||
| if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving && !havingHandledByFill) { |
There was a problem hiding this comment.
这个改动看上去是对的,但是没有新增测试用例,原来的测试用例有吗
| @@ -58,6 +58,7 @@ window_clause: { | |||
| SESSION(ts_col, tol_val) | |||
| | STATE_WINDOW(expr [, extend[, zeroth_state]]) [TRUE_FOR(true_for_expr)] | |||
| | INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [fill_clause] | |||
| "external_window((select ts, endtime, mark from ext_cx_win) w) " | ||
| "fill(none)", | ||
| ) | ||
| tdSql.checkRows(4) |
| "external_window((select ts, endtime, mark from ext_fill_win) w) fill(null) " | ||
| "order by ws" | ||
| ) | ||
| tdSql.checkRows(4) |
|
转 3.0 分支 |
Description
Issue(s)
Checklist
Please check the items in the checklist if applicable.