Skip to content

Conversation

@Sh-Zh-7
Copy link
Contributor

@Sh-Zh-7 Sh-Zh-7 commented Mar 20, 2025

As per title.

@Sh-Zh-7 Sh-Zh-7 marked this pull request as ready for review May 7, 2025 01:59
@JackieTien97 JackieTien97 requested a review from Copilot May 9, 2025 06:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR finalizes the window function query planning stage by introducing comprehensive support for window function analysis, planning, and execution.

  • Added new analysis methods and extraction utilities for window functions and expressions.
  • Extended the planner, execution operators, and window frame implementations to support window function operations.

Reviewed Changes

Copilot reviewed 52 out of 52 changed files in this pull request and generated no comments.

Show a summary per file
File Description
StatementAnalyzer.java Added imports and new methods to analyze window definitions and resolve window functions.
ExpressionTreeUtils.java Introduced static methods to extract window functions and nested window expressions.
ExpressionAnalyzer.java Updated logic to process window function calls and integrated window analysis into expression processing.
ExpressionAnalysis.java Extended analysis result to include window functions.
Analysis.java Added maps and methods to record window definitions, window functions, and order-by window functions.
PlanVisitor.java, PlanNodeType.java, PlanGraphPrinter.java Added new visit methods and node types to support window function planning and visualization.
TableOperatorGenerator.java Integrated the new window function operators into the query execution plan.
Various window frame and function files Updated window frame implementations and window function implementations (NthValue, Lead, Lag, NTile, etc.) to support new window query planning stage.
FilterAndProjectOperator.java Triggered evaluation in column transformers as part of the projection process.
Comments suppressed due to low confidence (1)

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/window/partition/frame/RangeFrame.java:78

  • [nitpick] Consider adding parentheses to clarify the operator precedence in this condition. For example: if ((frameInfo.getStartType() == UNBOUNDED_PRECEDING && frameInfo.getEndType() == UNBOUNDED_FOLLOWING) || noOrderBy) {
if (frameInfo.getStartType() == UNBOUNDED_PRECEDING && frameInfo.getEndType() == UNBOUNDED_FOLLOWING || noOrderBy) {

if (!hasNonMappableUDF) {
// get result of calculated common sub expressions
for (ColumnTransformer columnTransformer : commonTransformerList) {
columnTransformer.tryEvaluate();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add this new line? Are there any bugs before? If so, you may need to add IT about it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there is no .tryEvaluate, getColumn may return null.

builder.writeBoolean(partition.getBoolean(defaultValChannel, index));
return;
case TEXT:
case STRING:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about Blob?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

builder.writeBoolean(partition.getBoolean(defaultValChannel, index));
return;
case TEXT:
case STRING:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about BLOB

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
break;
case INT64:
case TIMESTAMP:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about DATE and BLOB

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}
break;
case INT64:
case TIMESTAMP:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about DATE and BLOB

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

// ignore
}

// now we only support scalar or agg functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deleted.

if (isAggregation) {
functionKind = FunctionKind.AGGREGATE;
} else {
boolean isWindow = metadata.isWindowFunction(session, functionName, accessControl);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if agg function used in window clause? It's FunctionKind.AGGREGATE or FunctionKind.WINDOW

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this function is aggregation function, we will still warp it into a window function instance.

if (functionKind == FunctionKind.AGGREGATE) {
WindowAggregator tableWindowAggregator =
buildWindowAggregator(symbol, function, typeProvider, argumentChannels);
windowFunction = new AggregationWindowFunction(tableWindowAggregator);
} else if (functionKind == FunctionKind.WINDOW) {


import static java.util.Objects.requireNonNull;

public class DataOrganizationSpecification {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deduplicated with org.apache.iotdb.db.queryengine.plan.relational.planner.DataOrganizationSpecification

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

public class QueryPlanner {
private final Analysis analysis;
private final SymbolAllocator symbolAllocator;
private final QueryId idAllocator;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not using queryIdAllocator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

.map(argument -> coercions.get(argument).toSymbolReference())
.collect(toImmutableList()),
frame,
// TODO: remove ignore null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should never have todo, fix it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like we already support IGNORE NULLS keyword. So this TODO is meanningless.

@Sh-Zh-7
Copy link
Contributor Author

Sh-Zh-7 commented May 29, 2025

PTAL~

@JackieTien97 JackieTien97 merged commit 7f916bb into apache:master May 30, 2025
56 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants