Skip to content
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

[CALCITE-6035] Unparse 'WITHIN GROUP' for BigQuery dialect to match BigQuery documentation #3466

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ public BigQuerySqlDialect(SqlDialect.Context context) {
}
unparseItem(writer, call, leftPrec);
break;
case WITHIN_GROUP:
unparseWithinGroup(writer, call, leftPrec, rightPrec);
break;
default:
super.unparseCall(writer, call, leftPrec, rightPrec);
}
Expand Down Expand Up @@ -292,6 +295,18 @@ private static void unparseItem(SqlWriter writer, SqlCall call, int leftPrec) {
writer.endList(frame);
}

private static void unparseWithinGroup(SqlWriter writer, SqlCall call, int leftPrec,
int rightPrec) {
assert call.operandCount() == 2;
call.operand(0).unparse(writer, 0, 0);
writer.keyword("OVER");
Copy link
Contributor

Choose a reason for hiding this comment

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

so I think you're more familiar with these clauses than me, is it guaranteed that the WITHIN GROUP translates to BQ's OVER in every case? are they really just synonyms for each other, I mean

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I detailed in this comment how Calcite currently only supports
select percentile_cont(0.5) within group (order by X)
so I want to say that for what is supported at this moment, it is sufficient

Copy link
Contributor

Choose a reason for hiding this comment

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

Ohhh ok. So if Calcite ended up supporting the partition by case (your input_2 from that comment), do you know if this would break?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Julian had a comment here about how we should approach the followup tickets
I think it won't work out of the box, there are things to figure out
We would still be parsing it as within_group in the parser, but want it to be handled differently in the validator.

questions to then consider: would we still use a SqlWithinGroupOperator? If yes, then that would be unparsed into "OVER" correctly. If not, this may have to change

final SqlWriter.Frame orderFrame =
writer.startList(SqlWriter.FrameTypeEnum.ORDER_BY_LIST, "(", ")");
writer.keyword("ORDER BY");
call.operand(1).unparse(writer, 0, 0);
writer.endList(orderFrame);
}

private static TimeUnit validate(TimeUnit timeUnit) {
switch (timeUnit) {
case MICROSECOND:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,19 @@ private static String toSql(RelNode root, SqlDialect dialect,
.withPostgresql().ok(expectedPostgresql);
}

@Test void testPercentileContWithinGroupClauseBigQuery() {
final String query = "select percentile_cont(0.5) WITHIN GROUP (ORDER BY `product_class_id`)\n"
+ "from `foodmart`.`product`";
final String expected = "SELECT PERCENTILE_CONT(0.5) OVER "
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the PERCENTILE_CONT function for BigQuery must have two arguments. I think this expected query would probably fail since the column isn't passed to the function directly as an argument

+ "(ORDER BY product_class_id NULLS LAST)\n"
+ "FROM foodmart.product";
final SqlParser.Config parserConfig =
olivrlee marked this conversation as resolved.
Show resolved Hide resolved
BigQuerySqlDialect.DEFAULT.configureParser(SqlParser.config());
final Sql sql = fixture()
.withBigQuery().withLibrary(SqlLibrary.BIG_QUERY).parserConfig(parserConfig);
sql.withSql(query).ok(expected);
}

/** Test case for
* <a href="https://issues.apache.org/jira/browse/CALCITE-2722">[CALCITE-2722]
* SqlImplementor createLeftCall method throws StackOverflowError</a>. */
Expand Down
Loading