15
15
*/
16
16
package org .springframework .data .jpa .repository .query ;
17
17
18
+ import static org .assertj .core .api .Assertions .*;
19
+ import static org .assertj .core .api .Assumptions .*;
20
+
21
+ import java .util .stream .Stream ;
22
+
23
+ import org .junit .jupiter .api .Test ;
24
+ import org .junit .jupiter .params .ParameterizedTest ;
25
+ import org .junit .jupiter .params .provider .Arguments ;
26
+ import org .junit .jupiter .params .provider .MethodSource ;
27
+ import org .springframework .data .domain .Sort ;
28
+
18
29
/**
19
30
* TCK Tests for {@link JSqlParserQueryEnhancer}.
20
31
*
21
32
* @author Mark Paluch
33
+ * @author Diego Krupitza
34
+ * @author Geoffrey Deremetz
22
35
*/
23
36
public class JSqlParserQueryEnhancerUnitTests extends QueryEnhancerTckTests {
24
37
@@ -27,4 +40,181 @@ QueryEnhancer createQueryEnhancer(DeclaredQuery declaredQuery) {
27
40
return new JSqlParserQueryEnhancer (declaredQuery );
28
41
}
29
42
43
+ @ Override
44
+ @ ParameterizedTest // GH-2773
45
+ @ MethodSource ("jpqlCountQueries" )
46
+ void shouldDeriveJpqlCountQuery (String query , String expected ) {
47
+
48
+ assumeThat (query ).as ("JSQLParser does not support simple JPQL syntax" ).doesNotStartWithIgnoringCase ("FROM" );
49
+
50
+ assumeThat (query ).as ("JSQLParser does not support constructor JPQL syntax" ).doesNotContain (" new " );
51
+
52
+ super .shouldDeriveJpqlCountQuery (query , expected );
53
+ }
54
+
55
+ @ Test
56
+ // GH-2578
57
+ void setOperationListWorks () {
58
+
59
+ String setQuery = "select SOME_COLUMN from SOME_TABLE where REPORTING_DATE = :REPORTING_DATE \n " //
60
+ + "except \n " //
61
+ + "select SOME_COLUMN from SOME_OTHER_TABLE where REPORTING_DATE = :REPORTING_DATE" ;
62
+
63
+ StringQuery stringQuery = new StringQuery (setQuery , true );
64
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
65
+
66
+ assertThat (stringQuery .getAlias ()).isNullOrEmpty ();
67
+ assertThat (stringQuery .getProjection ()).isEqualToIgnoringCase ("SOME_COLUMN" );
68
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
69
+
70
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (setQuery );
71
+ assertThat (queryEnhancer .applySorting (Sort .by ("SOME_COLUMN" ))).endsWith ("ORDER BY SOME_COLUMN ASC" );
72
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
73
+ assertThat (queryEnhancer .detectAlias ()).isNullOrEmpty ();
74
+ assertThat (queryEnhancer .getProjection ()).isEqualToIgnoringCase ("SOME_COLUMN" );
75
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
76
+ }
77
+
78
+ @ Test // GH-2578
79
+ void complexSetOperationListWorks () {
80
+
81
+ String setQuery = "select SOME_COLUMN from SOME_TABLE where REPORTING_DATE = :REPORTING_DATE \n " //
82
+ + "except \n " //
83
+ + "select SOME_COLUMN from SOME_OTHER_TABLE where REPORTING_DATE = :REPORTING_DATE \n " //
84
+ + "union select SOME_COLUMN from SOME_OTHER_OTHER_TABLE" ;
85
+
86
+ StringQuery stringQuery = new StringQuery (setQuery , true );
87
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
88
+
89
+ assertThat (stringQuery .getAlias ()).isNullOrEmpty ();
90
+ assertThat (stringQuery .getProjection ()).isEqualToIgnoringCase ("SOME_COLUMN" );
91
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
92
+
93
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (setQuery );
94
+ assertThat (queryEnhancer .applySorting (Sort .by ("SOME_COLUMN" ).ascending ())).endsWith ("ORDER BY SOME_COLUMN ASC" );
95
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
96
+ assertThat (queryEnhancer .detectAlias ()).isNullOrEmpty ();
97
+ assertThat (queryEnhancer .getProjection ()).isEqualToIgnoringCase ("SOME_COLUMN" );
98
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
99
+ }
100
+
101
+ @ Test // GH-2578
102
+ void deeplyNestedcomplexSetOperationListWorks () {
103
+
104
+ String setQuery = "SELECT CustomerID FROM (\n " //
105
+ + "\t \t \t select * from Customers\n " //
106
+ + "\t \t \t except\n " //
107
+ + "\t \t \t select * from Customers where country = 'Austria'\n " //
108
+ + "\t )\n " //
109
+ + "\t except\n " //
110
+ + "\t select CustomerID from customers where country = 'Germany'\n " //
111
+ + "\t ;" ;
112
+
113
+ StringQuery stringQuery = new StringQuery (setQuery , true );
114
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
115
+
116
+ assertThat (stringQuery .getAlias ()).isNullOrEmpty ();
117
+ assertThat (stringQuery .getProjection ()).isEqualToIgnoringCase ("CustomerID" );
118
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
119
+
120
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (setQuery );
121
+ assertThat (queryEnhancer .applySorting (Sort .by ("CustomerID" ).descending ())).endsWith ("ORDER BY CustomerID DESC" );
122
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
123
+ assertThat (queryEnhancer .detectAlias ()).isNullOrEmpty ();
124
+ assertThat (queryEnhancer .getProjection ()).isEqualToIgnoringCase ("CustomerID" );
125
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
126
+ }
127
+
128
+ @ Test // GH-2578
129
+ void valuesStatementsWorks () {
130
+
131
+ String setQuery = "VALUES (1, 2, 'test')" ;
132
+
133
+ StringQuery stringQuery = new StringQuery (setQuery , true );
134
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
135
+
136
+ assertThat (stringQuery .getAlias ()).isNullOrEmpty ();
137
+ assertThat (stringQuery .getProjection ()).isNullOrEmpty ();
138
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
139
+
140
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (setQuery );
141
+ assertThat (queryEnhancer .applySorting (Sort .by ("CustomerID" ).descending ())).isEqualTo (setQuery );
142
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
143
+ assertThat (queryEnhancer .detectAlias ()).isNullOrEmpty ();
144
+ assertThat (queryEnhancer .getProjection ()).isNullOrEmpty ();
145
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
146
+ }
147
+
148
+ @ Test // GH-2578
149
+ void withStatementsWorks () {
150
+
151
+ String setQuery = "with sample_data(day, value) as (values ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))) \n "
152
+ + "select day, value from sample_data as a" ;
153
+
154
+ StringQuery stringQuery = new StringQuery (setQuery , true );
155
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
156
+
157
+ assertThat (stringQuery .getAlias ()).isEqualToIgnoringCase ("a" );
158
+ assertThat (stringQuery .getProjection ()).isEqualToIgnoringCase ("day, value" );
159
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
160
+
161
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (
162
+ "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16)))\n "
163
+ + "SELECT count(1) FROM sample_data AS a" );
164
+ assertThat (queryEnhancer .applySorting (Sort .by ("day" ).descending ())).endsWith ("ORDER BY a.day DESC" );
165
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
166
+ assertThat (queryEnhancer .detectAlias ()).isEqualToIgnoringCase ("a" );
167
+ assertThat (queryEnhancer .getProjection ()).isEqualToIgnoringCase ("day, value" );
168
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
169
+ }
170
+
171
+ @ Test // GH-2578
172
+ void multipleWithStatementsWorks () {
173
+
174
+ String setQuery = "with sample_data(day, value) as (values ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))), test2 as (values (1,2,3)) \n "
175
+ + "select day, value from sample_data as a" ;
176
+
177
+ StringQuery stringQuery = new StringQuery (setQuery , true );
178
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
179
+
180
+ assertThat (stringQuery .getAlias ()).isEqualToIgnoringCase ("a" );
181
+ assertThat (stringQuery .getProjection ()).isEqualToIgnoringCase ("day, value" );
182
+ assertThat (stringQuery .hasConstructorExpression ()).isFalse ();
183
+
184
+ assertThat (queryEnhancer .createCountQueryFor ()).isEqualToIgnoringCase (
185
+ "with sample_data (day, value) AS (VALUES ((0, 13), (1, 12), (2, 15), (3, 4), (4, 8), (5, 16))),test2 AS (VALUES (1, 2, 3))\n "
186
+ + "SELECT count(1) FROM sample_data AS a" );
187
+ assertThat (queryEnhancer .applySorting (Sort .by ("day" ).descending ())).endsWith ("ORDER BY a.day DESC" );
188
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
189
+ assertThat (queryEnhancer .detectAlias ()).isEqualToIgnoringCase ("a" );
190
+ assertThat (queryEnhancer .getProjection ()).isEqualToIgnoringCase ("day, value" );
191
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
192
+ }
193
+
194
+ @ ParameterizedTest // GH-2641
195
+ @ MethodSource ("mergeStatementWorksSource" )
196
+ void mergeStatementWorksWithJSqlParser (String query , String alias ) {
197
+
198
+ StringQuery stringQuery = new StringQuery (query , true );
199
+ QueryEnhancer queryEnhancer = QueryEnhancerFactory .forQuery (stringQuery );
200
+
201
+ assertThat (queryEnhancer .detectAlias ()).isEqualTo (alias );
202
+ assertThat (QueryUtils .detectAlias (query )).isNull ();
203
+
204
+ assertThat (queryEnhancer .getJoinAliases ()).isEmpty ();
205
+ assertThat (queryEnhancer .detectAlias ()).isEqualTo (alias );
206
+ assertThat (queryEnhancer .getProjection ()).isEmpty ();
207
+ assertThat (queryEnhancer .hasConstructorExpression ()).isFalse ();
208
+ }
209
+
210
+ static Stream <Arguments > mergeStatementWorksSource () {
211
+
212
+ return Stream .of ( //
213
+ Arguments .of (
214
+ "merge into a using (select id, value from b) query on (a.id = query.id) when matched then update set a.value = value" ,
215
+ "query" ),
216
+ Arguments .of (
217
+ "merge into a using (select id2, value from b) on (id = id2) when matched then update set a.value = value" ,
218
+ null ));
219
+ }
30
220
}
0 commit comments