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

HHH-12492 Jpa DELETE Query generated has missing table alias and thus incorrect semantics #2439

Closed
wants to merge 3 commits into from

Conversation

yrodiere
Copy link
Member

https://hibernate.atlassian.net//browse/HHH-12492

Given the very sensitive section of the code I had to change, maybe we should wait for 5.4 before merging this. That being said, my first attempt was definitely buggy and at least 3 previously existing tests failed as a result, which is reassuring.

Copy link
Member

@gsmet gsmet left a comment

Choose a reason for hiding this comment

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

Added one minor comment.

@@ -172,7 +172,7 @@ public String getClassAlias() {
//return classAlias == null ? className : classAlias;
}

private String getTableName() {
public String getTableName() {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Right, I removed that.

…ueries in DELETE/UPDATE queries

Don't try to duplicate the logic from
org.hibernate.hql.internal.ast.tree.FromElementType#toColumns(java.lang.String, java.lang.String, boolean, boolean)
in other classes, it's complex enough and already seems to handle all
the cases we might encounter.

In this specific case, we want the table name to be used to qualify
column names, because the target table doesn't have any alias (it's not
supported by every version of every RDBMS), and not qualifying columns
at all may lead to a confusing statement, in particular if tables
referenced in the subquery contain columns with the same name.
Since we use aliases for every other table in the query, referencing the
table should not lead to any conflict.
@@ -197,14 +197,6 @@ private boolean resolveAsAlias() {

String[] columnExpressions = element.getIdentityColumns();
Copy link
Member

@gsmet gsmet Jul 19, 2018

Choose a reason for hiding this comment

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

So the general idea is to fix this getIdentityColumns() to avoid needing the workaround below.

This is done by using an existing logic doing exactly what we need.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep. Also, getIdentityColumns is only used in IdentNode#resolveAsAlias, so changing its behavior should not affect any other node or any other resolution of an IdentNode.

Copy link
Contributor

Choose a reason for hiding this comment

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

After some scrolling through the related code, and having played with FromElement recently, I can confirm that the replaced code in getIdentityColumns() was indeed a simplified version of what happened in the toColumns function now. The latter indeed has a special handling for subqueries. This change looks good to me!

@gbadner
Copy link
Contributor

gbadner commented Jul 25, 2018

I'm not familiar enough with this code to know for sure. @dreab8, can you take a look?

@gbadner gbadner requested a review from dreab8 July 25, 2018 18:26
@dreab8
Copy link
Contributor

dreab8 commented Jul 26, 2018

The PR looks fine to me just not 100% sure the change to the IdentNode is safe so I would limit the changes to the FromElement class

if ( getWalker().getStatementType() == HqlSqlTokenTypes.SELECT ) {
			return getPropertyMapping( propertyName ).toColumns( table, propertyName );
		}
		else {
			return toColumns(
					table, propertyName,
					getWalker().getStatementType() == HqlSqlTokenTypes.SELECT
			);
		}

this seems enough to solve the issue.

@gsmet
Copy link
Member

gsmet commented Jul 26, 2018

@dreab8 keep in mind that hte change in IdentNode is specifically manipulating a FromElement. As the element as been qualifier in FromElement itself, we don't need to do it again.

@yrodiere can you think of a case where keeping the code in IdentNode fails? I suppose it won't as there is this qualifyItNot() thing. But it's still better for correctness IMHO.

@yrodiere
Copy link
Member Author

@yrodiere can you think of a case where keeping the code in IdentNode fails? I suppose it won't as there is this qualifyItNot() thing. But it's still better for correctness IMHO.

I also think it's confusing and just wrong to keep this piece of code. But I doubt it will ever get executed, so I guess in this regard it's "safer" to keep it.

I pushed a fix-up commit that restores this piece of code, let's see if any test fails.

@beikov
Copy link
Contributor

beikov commented Jul 26, 2018

I haven't checked the details of the PR or specific DBMS, I just wanted to mention that I think this was done this way because some DBMS do not support an explicit alias for DML tables and instead require the use of the table name.

@sebersole
Copy link
Member

sebersole commented Jul 26, 2018 via email

@yrodiere
Copy link
Member Author

I haven't checked the details of the PR or specific DBMS, I just wanted to mention that I think this was done this way because some DBMS do not support an explicit alias for DML tables and instead require the use of the table name.

Yes, this was accounted for.

@yrodiere
Copy link
Member Author

To be clearer: FromElementType.toColumns will use the table name to qualify columns when the "fromelement" is the target of an update/delete query, where aliases cannot be used.

@gsmet
Copy link
Member

gsmet commented Jul 27, 2018

Merged, thanks!

@gsmet gsmet closed this Jul 27, 2018
@yrodiere yrodiere deleted the HHH-12492 branch June 26, 2019 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants