Skip to content

[CALCITE-5230] Fix PERCENTILE_DISC return type derivation #2868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

itiels
Copy link
Contributor

@itiels itiels commented Aug 9, 2022

Changed the return type of PERCENTILE_DISC to the type of the order_by_expression.

Ticket: CALCITE-5230

@@ -988,4 +990,15 @@ public static SqlCall stripSeparator(SqlCall call) {
return relDataType;
}
};

public static final SqlReturnTypeInference PERCENTILE_DISC = opBinding -> {
if (opBinding instanceof SqlWithinGroupOperator.PercentileDiscCallBinding) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This 'if .. instanceof ... else if ... instanceof' pattern isn't good. How about adding a method getCollationExpression() to SqlCallBinding, with a default implementation that throws. Then you can remove both getCollationType methods.

Copy link
Contributor Author

@itiels itiels Oct 3, 2022

Choose a reason for hiding this comment

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

I can't implement getCollationExpression in PercentileDiscAggCallBinding, as I don't have the collation expression there. (maybe i'm missing something).
I can however add getCollationType to the base class which will remove the need to use the instance of pattern here.

} else {
return validateOperands(validator, scope, call);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a lot of duplicated code here. Maybe if you replace new SqlCallBinding(validator, scope, call) in the base method with a protected method, you can save all that duplication?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we can, because the validation/derivation is needed to be done in terms of the inner operator. even if we supply the correct SqlCallBinding to validateOperands, it will still be done in the context of the outer operator(SqlWithinGroupOperator)

@itiels itiels force-pushed the CALCITE-5230 branch 2 times, most recently from 5c86873 to b0e6502 Compare October 3, 2022 10:45
Copy link
Member

@libenchao libenchao left a comment

Choose a reason for hiding this comment

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

@itiels Thanks for your PR, generally it looks good now, I only left one minor comment.

Besides, PERCENTILE_COUT also should be fixed, we can do it in this issue, or a follow-up issue.

@@ -2303,7 +2303,7 @@ public class SqlStdOperatorTable extends ReflectiveSqlOperatorTable {
*/
public static final SqlAggFunction PERCENTILE_DISC =
SqlBasicAggFunction
.create(SqlKind.PERCENTILE_DISC, ReturnTypes.DOUBLE,
.create(SqlKind.PERCENTILE_DISC, ReturnTypes.PERCENTILE_DISC,
Copy link
Member

Choose a reason for hiding this comment

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

The java doc should also be adjusted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, fixed it

@itiels
Copy link
Contributor Author

itiels commented Nov 11, 2022

Thanks @libenchao for the review.

I've fixed the comment.
As for PERCENTILE_CONT, based on conversation with Julian in the Jira ticket, there is nothing to be done.

Is there anything else that I need/should to do for this PR?

@libenchao
Copy link
Member

As for PERCENTILE_CONT, based on conversation with Julian in the Jira ticket, there is nothing to be done.

I'm not sure about this conclusion, I've checked the SQL standard (2011), 10.9:

If PERCENTILE_CONT is specified, then:

  1. Let ROW0 be the greatest exact numeric value with scale 0 (zero) that is less than or equal
    to NVE*(N–1). Let ROWLIT0 be a representing ROW0.
  2. Let ROW1 be the least exact numeric value with scale 0 (zero) that is greater than or equal to NVE*(N–1). Let ROWLIT1 be a representing ROW1.
  3. Let FACTOR be an representing NVE*(N–1)–ROW0.
  4. The result is the result of the
    ( WITH TEMPTABLE(X, Y) AS
    ( SELECT ROW_NUMBER()
    OVER (ORDER BY WSP) - 1, TXCOLNAME
    FROM TXANAME )
    SELECT CAST ( T0.Y + FACTOR * (T1.Y - T0.Y) AS DT ) FROM TEMPTABLE T0, TEMPTABLE T1
    WHERE T0.ROWNUMBER = ROWLIT0
    AND T1.ROWNUMBER = ROWLIT1 )

We can see that the standard is using CAST ( T0.Y + FACTOR * (T1.Y - T0.Y) AS DT ) as the result for PERCENTILE_COUT, whose type is the same as the sort key.

And also I've checked some databases, and found: oracle and postgrelsql are consistent with the standard.

There are some databases, such as server sql, are declaring the return type which is not consistent with the standard.

Hence, IMO, we should make it consistent with the standard by default. Of course if could be extensible for some dialects, if we want to achieve that, maybe the proper place to add the extension is in RelDataTypeSystem

@libenchao libenchao self-assigned this Nov 28, 2022
@libenchao
Copy link
Member

@itiels Sorry to ping you.
We plan to release 1.33 recently, it would be great if we can make it in this release. Do you have any comments about my last comment?

@itiels
Copy link
Contributor Author

itiels commented Nov 28, 2022

HI @libenchao,
Sorry for the late reply.

I agree with your conclusion, however I prefer to do that in a separate PR if it's ok with you.

@libenchao
Copy link
Member

I'm ok with finishing it to another separate issue.
This PR now looks good to me. The CI failure seems unrelated, I'll merge it.

@julianhyde
Copy link
Contributor

@libenchao when you merge, please change the commit message to something that doesn’t start with “fix”

@libenchao
Copy link
Member

@julianhyde Very thanks for the reminder 👍 , I did plan to do that while merging.

@libenchao libenchao closed this in 9161a6f Nov 30, 2022
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.

3 participants