-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix order by rendering for queries containing UNION #3429
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
Conversation
void sortShouldBeAppendedWithSpacingInCaseOfSetOperator() { | ||
|
||
String source = "SELECT tb FROM Test tb WHERE (tb.type='A') UNION SELECT tb FROM Test tb WHERE (tb.type='B')"; | ||
String target = createQueryFor(source, Sort.by("Type").ascending()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After this line target
has the value
SELECT tb
FROM Test tb
WHERE (tb.type = 'A')
order by tb.Type asc
UNION
SELECT tb
FROM Test tb
WHERE (tb.type = 'B')
order by tb.Type asc`
i.e. the order by
is applied twice which is illegal, since according to answers here https://stackoverflow.com/questions/4715820/how-to-order-by-with-union-in-sql the later order by
applies to the full union
and an order by
on the individual selects might be even illegal (probably depends on the database)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we do not know the target db nor how it handles order by we cannot imply ordering the last is the correct behaviour, nor do we have the means to define which of the selects to decorate. an alternative would be to raise an error and demand wrapping the entire thing as it's done in one of the follow up tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably, let's wait and see what kind of reports we get. We can then still react to the feedback we receive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reading through IBM an Oracle SQL reference docs @schauder has a good point in the above mentioned query not being compliant (at least not in the form it is currently rendered)
For example, the following is not valid (SQLSTATE 428FJ):
SELECT * FROM T1
ORDER BY C1
UNION
SELECT * FROM T2
ORDER BY C1
The following example is valid:
(SELECT * FROM T1
ORDER BY C1)
UNION
(SELECT * FROM T2
ORDER BY C1)
String source = "SELECT tb FROM Test tb WHERE (tb.type='A') UNION SELECT tb FROM Test tb WHERE (tb.type='B')"; | ||
String target = createQueryFor(source, Sort.by("Type").ascending()); | ||
|
||
assertThat(target).contains(" UNION SELECT ").doesNotContainPattern(Pattern.compile(".*\\SUNION")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we put in an exact SQL statement we should be able to assert on a precise output and not rely on pattern matching and simiar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems legit
} | ||
|
||
@ParameterizedTest // GH-3427 | ||
@ValueSource(strings = {"", "res"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment would be nice explaining why we need to run this with different prefixes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deemed to be obvious - apparently isn't
@ValueSource(strings = {"", "res"}) | ||
void sortShouldBeAppendedToSubSelectWithSetOperatorInSubselect(String alias) { | ||
|
||
String prefix = StringUtils.hasText(alias) ? (alias + ".") : ""; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I think we should be able to and prefer a simple equals-assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of duplication.
we should additionally check the count query creation for |
Make sure to append space after order by clause and fix alias detection for wrapped sub select. Also make sure to ignore alias used in subselect so they do not conflict with root ones.
d092eb8
to
82b28a4
Compare
Updated the HQL code to apply ordering after the last set operation, EQL did that already. |
Make sure to append space after order by clause and fix alias detection for wrapped sub select. Also make sure to ignore alias used in subselect so they do not conflict with root ones. Render order by only on full select if set operator is present in EQL. Closes #3630 Original pull request: #3429 See #3427
Make sure to append space after order by clause and fix alias detection for wrapped sub select. Also make sure to ignore alias used in subselect so they do not conflict with root ones. Render order by only on full select if set operator is present in EQL. Closes #3630 Original pull request: #3429 See #3427
Make sure to append space after order by clause and fix alias detection for wrapped sub select.
Also make sure to ignore alias used in subselect so they do not conflict with root ones.
Closes: #3427