Skip to content

Commit b0d8ff7

Browse files
borgiirivelo
andauthored
Merge using updates to 5.0.0 (#122)
* Enable merge using test on H2 * Bump Postgres, enable merge using test for postgres * More merge using tests * Bump version of postgres used for tests * Make merging table to table work --------- Co-authored-by: Marvin Froeder <[email protected]>
1 parent e9f2489 commit b0d8ff7

17 files changed

+222
-53
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ jobs:
144144
working_directory: ~/querydsl
145145
docker:
146146
- image: velo/toolchains-4-ci-builds:with-21
147-
- image: mdillon/postgis:9.3-alpine
147+
- image: postgis/postgis:16-3.4-alpine
148148
environment:
149149
- POSTGRES_USER=querydsl
150150
- POSTGRES_PASSWORD=querydsl

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ For more information visit the project homepage at https://querydsl.github.io.
7777
For running tests, a Docker Compose setup is provided. It comes with the following databases:
7878

7979
* Oracle Express Edition 11g
80-
* PostgreSQL 9.1.10
80+
* PostgreSQL 16
8181
* MySQL 5.5.34
8282
* Cubrid 9.2
8383

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ services:
2323
- MYSQL_PASSWORD=querydsl
2424

2525
postgresql:
26-
image: mdillon/postgis:9.3-alpine
26+
image: postgis/postgis:16-3.4-alpine
2727
ports:
2828
- "5432:5432"
2929
volumes:

querydsl-sql/src/main/java/com/querydsl/sql/SQLSerializer.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,25 @@ public void serializeForMergeUsing(
578578
handle(entity);
579579
dmlWithSchema = originalDmlWithSchema;
580580
append("\nusing ");
581+
582+
// A hacky way to allow merging table to table directly
583+
if (usingExpression instanceof RelationalPath) {
584+
dmlWithSchema = true;
585+
// If table has an alias, handle both original table name and alias
586+
if (!((RelationalPath<?>) usingExpression)
587+
.getTableName()
588+
.equals(ColumnMetadata.getName((RelationalPath<?>) usingExpression))) {
589+
RelationalPath<?> originalEntity = this.entity;
590+
this.entity = (RelationalPath<?>) usingExpression;
591+
handle(usingExpression);
592+
append(" ");
593+
this.entity = originalEntity;
594+
dmlWithSchema = originalDmlWithSchema;
595+
}
596+
}
581597
handle(usingExpression);
598+
dmlWithSchema = originalDmlWithSchema;
599+
582600
append("\n");
583601
append(templates.getOn());
584602
handle(usingOn);

querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,9 @@
2424
import com.querydsl.core.types.Path;
2525
import com.querydsl.core.types.dsl.Expressions;
2626
import com.querydsl.sql.dml.SQLMergeClause;
27-
import com.querydsl.sql.dml.SQLMergeUsingClause;
2827
import com.querydsl.sql.domain.QSurvey;
2928
import java.sql.ResultSet;
3029
import java.sql.SQLException;
31-
import java.util.Arrays;
32-
import java.util.Collections;
3330
import java.util.concurrent.atomic.AtomicBoolean;
3431
import java.util.concurrent.atomic.AtomicInteger;
3532
import org.junit.After;
@@ -236,33 +233,6 @@ public void merge_with_templateExpression_in_batch() {
236233
assertEquals(1, merge.execute());
237234
}
238235

239-
@Test
240-
@IncludeIn({DB2, SQLSERVER})
241-
public void merge_with_using() {
242-
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
243-
SQLMergeUsingClause merge =
244-
merge(survey)
245-
.using(
246-
query()
247-
.from(survey2)
248-
.select(survey2.id.add(40).as("ID"), survey2.name)
249-
.as(usingSubqueryAlias))
250-
.on(survey.id.eq(usingSubqueryAlias.id))
251-
.whenNotMatched()
252-
.thenInsert(
253-
Arrays.asList(survey.id, survey.name),
254-
Arrays.asList(usingSubqueryAlias.id, usingSubqueryAlias.name))
255-
.whenMatched()
256-
.and(survey.id.goe(10))
257-
.thenDelete()
258-
.whenMatched()
259-
.thenUpdate(
260-
Collections.singletonList(survey.name),
261-
Collections.singletonList(usingSubqueryAlias.name));
262-
263-
assertEquals(1, merge.execute());
264-
}
265-
266236
@Test
267237
public void merge_listener() {
268238
final AtomicInteger calls = new AtomicInteger(0);
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.querydsl.sql;
15+
16+
import static com.querydsl.core.Target.*;
17+
import static com.querydsl.sql.Constants.*;
18+
import static org.junit.Assert.*;
19+
20+
import com.querydsl.core.testutil.IncludeIn;
21+
import com.querydsl.sql.dml.SQLMergeUsingClause;
22+
import com.querydsl.sql.domain.QEmployee;
23+
import com.querydsl.sql.domain.QSurvey;
24+
import java.sql.SQLException;
25+
import java.util.Arrays;
26+
import java.util.Collections;
27+
import java.util.List;
28+
import org.junit.After;
29+
import org.junit.Before;
30+
import org.junit.Test;
31+
32+
public class MergeUsingBase extends AbstractBaseTest {
33+
34+
private void reset() throws SQLException {
35+
delete(survey).execute();
36+
insert(survey).values(1, "Hello World", "Hello").execute();
37+
}
38+
39+
@Before
40+
public void setUp() throws SQLException {
41+
reset();
42+
}
43+
44+
@After
45+
public void tearDown() throws SQLException {
46+
reset();
47+
}
48+
49+
@Test
50+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
51+
public void merge_with_using() {
52+
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
53+
SQLMergeUsingClause merge =
54+
merge(survey)
55+
.using(
56+
query()
57+
.from(survey2)
58+
.select(survey2.id.add(40).as("ID"), survey2.name)
59+
.as(usingSubqueryAlias))
60+
.on(survey.id.eq(usingSubqueryAlias.id))
61+
.whenNotMatched()
62+
.thenInsert(
63+
Arrays.asList(survey.id, survey.name),
64+
Arrays.asList(usingSubqueryAlias.id, usingSubqueryAlias.name))
65+
.whenMatched()
66+
.and(survey.id.goe(10))
67+
.thenDelete()
68+
.whenMatched()
69+
.thenUpdate(
70+
Collections.singletonList(survey.name),
71+
Collections.singletonList(usingSubqueryAlias.name));
72+
73+
assertEquals(1, merge.execute());
74+
}
75+
76+
@Test
77+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
78+
public void merge_with_using_insert() {
79+
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
80+
SQLMergeUsingClause merge =
81+
merge(survey)
82+
.using(
83+
query()
84+
.from(survey2)
85+
.select(survey2.id.add(40).as("ID"), survey2.name)
86+
.as(usingSubqueryAlias))
87+
.on(survey.id.eq(usingSubqueryAlias.id))
88+
.whenNotMatched()
89+
.thenInsert(
90+
Arrays.asList(survey.id, survey.name),
91+
Arrays.asList(usingSubqueryAlias.id, usingSubqueryAlias.name));
92+
93+
assertEquals(1, merge.execute());
94+
}
95+
96+
@Test
97+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
98+
public void merge_with_using_delete() {
99+
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
100+
SQLMergeUsingClause merge =
101+
merge(survey)
102+
.using(query().from(survey2).select(survey2.id, survey2.name).as(usingSubqueryAlias))
103+
.on(survey.id.eq(usingSubqueryAlias.id))
104+
.whenMatched()
105+
.thenDelete();
106+
107+
assertEquals(1, merge.execute());
108+
}
109+
110+
@Test
111+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
112+
public void merge_with_using_update() {
113+
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
114+
SQLMergeUsingClause merge =
115+
merge(survey)
116+
.using(
117+
query()
118+
.from(survey2)
119+
.select(survey2.id, survey2.name.append("new").as("NAME"))
120+
.as(usingSubqueryAlias))
121+
.on(survey.id.eq(usingSubqueryAlias.id))
122+
.whenMatched()
123+
.thenUpdate(List.of(survey.name), List.of(usingSubqueryAlias.name));
124+
125+
assertEquals(1, merge.execute());
126+
}
127+
128+
@Test
129+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
130+
public void merge_with_using_extra_filter() {
131+
QSurvey usingSubqueryAlias = new QSurvey("USING_SUBSELECT");
132+
SQLMergeUsingClause merge =
133+
merge(survey)
134+
.using(query().from(survey2).select(survey2.id, survey2.name).as(usingSubqueryAlias))
135+
.on(survey.id.eq(usingSubqueryAlias.id))
136+
.whenMatched()
137+
.and(usingSubqueryAlias.id.lt(0))
138+
.thenDelete();
139+
140+
assertEquals(0, merge.execute());
141+
}
142+
143+
@Test
144+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
145+
public void merge_with_using_direct_table_with_alias() {
146+
SQLMergeUsingClause merge =
147+
merge(survey).using(employee).on(survey.id.eq(employee.id)).whenMatched().thenDelete();
148+
149+
assertEquals(1, merge.execute());
150+
}
151+
152+
@Test
153+
@IncludeIn({DB2, SQLSERVER, H2, POSTGRESQL})
154+
public void merge_with_using_direct_table_no_alias() {
155+
SQLMergeUsingClause merge =
156+
merge(survey)
157+
.using(QEmployee.employee)
158+
.on(survey.id.eq(QEmployee.employee.id))
159+
.whenMatched()
160+
.thenDelete();
161+
162+
assertEquals(1, merge.execute());
163+
}
164+
}

querydsl-sql/src/test/java/com/querydsl/sql/SelectBase.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.sql.Timestamp;
3838
import java.util.*;
3939
import java.util.concurrent.atomic.AtomicLong;
40+
import org.apache.commons.compress.utils.Sets;
4041
import org.joda.time.*;
4142
import org.junit.Assert;
4243
import org.junit.Ignore;
@@ -2505,35 +2506,31 @@ public void end(SQLListenerContext context) {
25052506
@Test
25062507
@ExcludeIn({DB2, DERBY, ORACLE, SQLSERVER})
25072508
public void groupConcat() {
2508-
List<String> expected =
2509-
Arrays.asList("Mike,Mary", "Joe,Peter,Steve,Jim", "Jennifer,Helen,Daisy,Barbara");
2510-
if (Connections.getTarget() == POSTGRESQL) {
2511-
expected = Arrays.asList("Steve,Jim,Joe,Peter", "Barbara,Helen,Daisy,Jennifer", "Mary,Mike");
2512-
}
2509+
HashSet<String> expected =
2510+
Sets.newHashSet("Mike,Mary", "Joe,Peter,Steve,Jim", "Jennifer,Helen,Daisy,Barbara");
25132511
assertEquals(
25142512
expected,
2515-
query()
2516-
.select(SQLExpressions.groupConcat(employee.firstname))
2517-
.from(employee)
2518-
.groupBy(employee.superiorId)
2519-
.fetch());
2513+
new HashSet<>(
2514+
query()
2515+
.select(SQLExpressions.groupConcat(employee.firstname))
2516+
.from(employee)
2517+
.groupBy(employee.superiorId)
2518+
.fetch()));
25202519
}
25212520

25222521
@Test
25232522
@ExcludeIn({DB2, DERBY, ORACLE, SQLSERVER})
25242523
public void groupConcat2() {
2525-
List<String> expected =
2526-
Arrays.asList("Mike-Mary", "Joe-Peter-Steve-Jim", "Jennifer-Helen-Daisy-Barbara");
2527-
if (Connections.getTarget() == POSTGRESQL) {
2528-
expected = Arrays.asList("Steve-Jim-Joe-Peter", "Barbara-Helen-Daisy-Jennifer", "Mary-Mike");
2529-
}
2524+
HashSet<String> expected =
2525+
Sets.newHashSet("Mike-Mary", "Joe-Peter-Steve-Jim", "Jennifer-Helen-Daisy-Barbara");
25302526
assertEquals(
25312527
expected,
2532-
query()
2533-
.select(SQLExpressions.groupConcat(employee.firstname, "-"))
2534-
.from(employee)
2535-
.groupBy(employee.superiorId)
2536-
.fetch());
2528+
new HashSet<>(
2529+
query()
2530+
.select(SQLExpressions.groupConcat(employee.firstname, "-"))
2531+
.from(employee)
2532+
.groupBy(employee.superiorId)
2533+
.fetch()));
25372534
}
25382535
}
25392536
// CHECKSTYLERULE:ON: FileLength

querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2LiteralsSuiteTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public static class LikeEscape extends LikeEscapeBase {}
2020

2121
public static class Merge extends MergeBase {}
2222

23+
public static class MergeUsing extends MergeUsingBase {}
24+
2325
public static class Select extends SelectBase {}
2426

2527
public static class SelectWindowFunctions extends SelectWindowFunctionsBase {}

querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2SuiteTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public static class LikeEscape extends LikeEscapeBase {}
2020

2121
public static class Merge extends MergeBase {}
2222

23+
public static class MergeUsing extends MergeUsingBase {}
24+
2325
public static class Select extends SelectBase {}
2426

2527
public static class SelectWindowFunctions extends SelectWindowFunctionsBase {}

querydsl-sql/src/test/java/com/querydsl/sql/suites/H2LiteralsSuiteTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public static class LikeEscape extends LikeEscapeBase {}
2020

2121
public static class Merge extends MergeBase {}
2222

23+
public static class MergeUsing extends MergeUsingBase {}
24+
2325
public static class Select extends SelectBase {}
2426

2527
public static class Subqueries extends SubqueriesBase {}

0 commit comments

Comments
 (0)