Skip to content

Commit 92a830a

Browse files
Emanuele Gesuatosebersole
authored andcommitted
HHH-5946 - Wrong SQL generated when composites are compared using not-equal operator
(cherry picked from commit cd2b031)
1 parent 7612f8c commit 92a830a

File tree

8 files changed

+585
-12
lines changed

8 files changed

+585
-12
lines changed

hibernate-core/src/main/java/org/hibernate/hql/internal/ast/tree/BinaryLogicOperatorNode.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.hibernate.TypeMismatchException;
1313
import org.hibernate.engine.spi.SessionFactoryImplementor;
1414
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
15+
import org.hibernate.hql.internal.ast.QuerySyntaxException;
1516
import org.hibernate.hql.internal.ast.util.ColumnHelper;
1617
import org.hibernate.internal.util.StringHelper;
1718
import org.hibernate.param.ParameterSpecification;
@@ -110,8 +111,22 @@ private void mutateRowValueConstructorSyntax(int valueElements) {
110111
// mutation depends on the types of nodes involved...
111112
int comparisonType = getType();
112113
String comparisonText = getText();
113-
setType( HqlSqlTokenTypes.AND );
114-
setText( "AND" );
114+
115+
switch ( comparisonType ) {
116+
case HqlSqlTokenTypes.EQ:
117+
setType( HqlSqlTokenTypes.AND );
118+
setText( "AND" );
119+
break;
120+
121+
case HqlSqlTokenTypes.NE:
122+
setType( HqlSqlTokenTypes.OR );
123+
setText( "OR" );
124+
break;
125+
126+
default:
127+
throw new QuerySyntaxException( comparisonText + " operator not supported on composite types." );
128+
}
129+
115130
String[] lhsElementTexts = extractMutationTexts( getLeftHandOperand(), valueElements );
116131
String[] rhsElementTexts = extractMutationTexts( getRightHandOperand(), valueElements );
117132

@@ -175,7 +190,7 @@ protected void translate(
175190
AST rhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[i] );
176191
op.setFirstChild( lhs );
177192
lhs.setNextSibling( rhs );
178-
AST newContainer = getASTFactory().create( HqlSqlTokenTypes.AND, "AND" );
193+
AST newContainer = getASTFactory().create( container.getType(), container.getText() );
179194
container.setFirstChild( newContainer );
180195
newContainer.setNextSibling( op );
181196
container = newContainer;
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* Copyright (c) 2014, Red Hat Inc. or third-party contributors as
5+
* indicated by the @author tags or express copyright attribution
6+
* statements applied by the authors. All third-party contributions are
7+
* distributed under license by Red Hat Inc.
8+
*
9+
* This copyrighted material is made available to anyone wishing to use, modify,
10+
* copy, or redistribute it subject to the terms and conditions of the GNU
11+
* Lesser General Public License, as published by the Free Software Foundation.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15+
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
16+
* for more details.
17+
*
18+
* You should have received a copy of the GNU Lesser General Public License
19+
* along with this distribution; if not, write to:
20+
* Free Software Foundation, Inc.
21+
* 51 Franklin Street, Fifth Floor
22+
* Boston, MA 02110-1301 USA
23+
*/
24+
package org.hibernate.test.cut;
25+
26+
import java.io.Serializable;
27+
28+
/**
29+
* Class for testing composite user types with more than two fields.
30+
*
31+
* @author Etienne Miret
32+
*/
33+
public class CompositeDateTime implements Serializable {
34+
35+
private static final long serialVersionUID = 7401750071679578453L;
36+
37+
private Integer year;
38+
39+
private Integer month;
40+
41+
private Integer day;
42+
43+
private Integer hour;
44+
45+
private Integer minute;
46+
47+
private Integer second;
48+
49+
public CompositeDateTime(final Integer year, final Integer month, final Integer day, final Integer hour,
50+
final Integer minute, final Integer second) {
51+
super();
52+
this.year = year;
53+
this.month = month;
54+
this.day = day;
55+
this.hour = hour;
56+
this.minute = minute;
57+
this.second = second;
58+
}
59+
60+
/*
61+
* Constructor for those who hate auto (un)boxing.
62+
*/
63+
public CompositeDateTime(final int year, final int month, final int day, final int hour,
64+
final int minute, final int second) {
65+
this( new Integer( year ), Integer.valueOf( month ), Integer.valueOf( day ), Integer.valueOf( hour ),
66+
Integer.valueOf( minute ), Integer.valueOf( second ) );
67+
}
68+
69+
public CompositeDateTime(final CompositeDateTime other) {
70+
super();
71+
this.year = other.year;
72+
this.month = other.month;
73+
this.day = other.day;
74+
this.hour = other.hour;
75+
this.minute = other.minute;
76+
this.second = other.second;
77+
}
78+
79+
public Integer getYear() {
80+
return year;
81+
}
82+
83+
public void setYear(final Integer year) {
84+
this.year = year;
85+
}
86+
87+
public Integer getMonth() {
88+
return month;
89+
}
90+
91+
public void setMonth(final Integer month) {
92+
this.month = month;
93+
}
94+
95+
public Integer getDay() {
96+
return day;
97+
}
98+
99+
public void setDay(final Integer day) {
100+
this.day = day;
101+
}
102+
103+
public Integer getHour() {
104+
return hour;
105+
}
106+
107+
public void setHour(final Integer hour) {
108+
this.hour = hour;
109+
}
110+
111+
public Integer getMinute() {
112+
return minute;
113+
}
114+
115+
public void setMinute(final Integer minute) {
116+
this.minute = minute;
117+
}
118+
119+
public Integer getSecond() {
120+
return second;
121+
}
122+
123+
public void setSecond(final Integer second) {
124+
this.second = second;
125+
}
126+
127+
@Override
128+
public int hashCode() {
129+
final int prime = 31;
130+
int result = 1;
131+
result = prime * result + ( ( day == null ) ? 0 : day.hashCode() );
132+
result = prime * result + ( ( hour == null ) ? 0 : hour.hashCode() );
133+
result = prime * result + ( ( minute == null ) ? 0 : minute.hashCode() );
134+
result = prime * result + ( ( month == null ) ? 0 : month.hashCode() );
135+
result = prime * result + ( ( second == null ) ? 0 : second.hashCode() );
136+
result = prime * result + ( ( year == null ) ? 0 : year.hashCode() );
137+
return result;
138+
}
139+
140+
@Override
141+
public boolean equals(Object obj) {
142+
if ( this == obj ) {
143+
return true;
144+
}
145+
if ( obj == null ) {
146+
return false;
147+
}
148+
if ( !( obj instanceof CompositeDateTime ) ) {
149+
return false;
150+
}
151+
CompositeDateTime other = (CompositeDateTime) obj;
152+
if ( day == null ) {
153+
if ( other.day != null ) {
154+
return false;
155+
}
156+
}
157+
else if ( !day.equals( other.day ) ) {
158+
return false;
159+
}
160+
if ( hour == null ) {
161+
if ( other.hour != null ) {
162+
return false;
163+
}
164+
}
165+
else if ( !hour.equals( other.hour ) ) {
166+
return false;
167+
}
168+
if ( minute == null ) {
169+
if ( other.minute != null ) {
170+
return false;
171+
}
172+
}
173+
else if ( !minute.equals( other.minute ) ) {
174+
return false;
175+
}
176+
if ( month == null ) {
177+
if ( other.month != null ) {
178+
return false;
179+
}
180+
}
181+
else if ( !month.equals( other.month ) ) {
182+
return false;
183+
}
184+
if ( second == null ) {
185+
if ( other.second != null ) {
186+
return false;
187+
}
188+
}
189+
else if ( !second.equals( other.second ) ) {
190+
return false;
191+
}
192+
if ( year == null ) {
193+
if ( other.year != null ) {
194+
return false;
195+
}
196+
}
197+
else if ( !year.equals( other.year ) ) {
198+
return false;
199+
}
200+
return true;
201+
}
202+
203+
}

0 commit comments

Comments
 (0)