Skip to content

[CALCITE-7701] Support IGNORE NULLS for FIRST_VALUE/LAST_VALUE window functions in the enumerable convention - #5178

Open
xuzifu666 wants to merge 3 commits into
apache:mainfrom
xuzifu666:support_ig
Open

[CALCITE-7701] Support IGNORE NULLS for FIRST_VALUE/LAST_VALUE window functions in the enumerable convention#5178
xuzifu666 wants to merge 3 commits into
apache:mainfrom
xuzifu666:support_ig

Conversation

@xuzifu666

Copy link
Copy Markdown
Member

from emp": FILTER clause is not supported for window function FIRST_VALUE
!error

# [CALCITE-7701] Support IGNORE NULLS for FIRST_VALUE/LAST_VALUE window functions in the enumerable convention

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

These SQL programs had been validated in Oracle: https://onecompiler.com/oracle/44xqcbrnw

? Expressions.postIncrementAssign(idx)
: Expressions.postDecrementAssign(idx);

final BlockBuilder loopBody = winResult.nestBlock();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you add comments showing the generated Java code for each of these statements?
This would make it much easier to maintain the code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

OK, I had added comments showing the generated code.
The method Javadoc now includes a full pseudo-code snippet of the generated block (for FIRST_VALUE; LAST_VALUE scans backward), and I added inline comments before the loop body and the if (hasRows) { for (...) } wrapper to show what each statement generates.

/**
* Implements FIRST_VALUE / LAST_VALUE with IGNORE NULLS by scanning the
* frame (forward for FIRST_VALUE, backward for LAST_VALUE) and returning
* the first non-null argument value, or the default value if all rows in

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is the "default value"? Isn't it always null?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You're right, the default value is always null here. I changed the Javadoc from "or the default value if all rows..." to "or null if all rows..." to be explicit.

Expressions.parameter(0, boxType,
winResult.currentBlock().newName(
seekType == SeekType.START ? "first_value" : "last_value"));
winResult.currentBlock().add(Expressions.declare(0, res, NULL_EXPR));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It seems to be that this is the default value, so it is NULL.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, the NULL_EXPR passed to Expressions.declare initializes res to null, which is the default value returned when the frame is empty or every row in the frame is null. This matches the behavior in the non-IGNORE NULLS path, where getDefaultValue(info.returnType()) also produces null for these functions. I kept the code as-is because the surrounding Javadoc now explicitly says "or null if all rows in the frame are null", so the intent should be clear from the documentation.

@sonarqubecloud

Copy link
Copy Markdown

# Verified against Oracle
# FIRST_VALUE with IGNORE NULLS returns the first non-null value in the frame
# (or NULL if the frame is empty or all values are null).
select o, v,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

all these tests have a finite window with ROWS.
How does this work for unbounded windows or RANGE windows?
You need much better test coverage.

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