Skip to content

Commit 0909a35

Browse files
authored
Support for top level IfBlock and ForBlock directives in SQL transformation (#840)
1 parent a06fbaa commit 0909a35

File tree

6 files changed

+93
-27
lines changed

6 files changed

+93
-27
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.seasar.doma.internal.jdbc.dialect;
2+
3+
import org.seasar.doma.internal.jdbc.sql.SimpleSqlNodeVisitor;
4+
import org.seasar.doma.internal.jdbc.sql.node.ElseifNode;
5+
import org.seasar.doma.internal.jdbc.sql.node.EndNode;
6+
import org.seasar.doma.internal.jdbc.sql.node.ForBlockNode;
7+
import org.seasar.doma.internal.jdbc.sql.node.IfBlockNode;
8+
import org.seasar.doma.jdbc.SqlNode;
9+
10+
abstract class AbstractTransformer extends SimpleSqlNodeVisitor<SqlNode, Void> {
11+
12+
@Override
13+
protected SqlNode defaultAction(SqlNode node, Void p) {
14+
return node;
15+
}
16+
17+
@Override
18+
public SqlNode visitForBlockNode(ForBlockNode node, Void unused) {
19+
ForBlockNode result = new ForBlockNode();
20+
result.setForNode(node.getForNode());
21+
result.setEndNode(visitEndNode(node.getEndNode(), unused));
22+
return result;
23+
}
24+
25+
@Override
26+
public SqlNode visitIfBlockNode(IfBlockNode node, Void unused) {
27+
IfBlockNode result = new IfBlockNode();
28+
result.setIfNode(node.getIfNode());
29+
for (ElseifNode elseifNode : node.getElseifNodes()) {
30+
result.addElseifNode(elseifNode);
31+
}
32+
if (node.isElseNodeExistent()) {
33+
result.setElseNode(node.getElseNode());
34+
}
35+
result.setEndNode(visitEndNode(node.getEndNode(), unused));
36+
return result;
37+
}
38+
39+
@Override
40+
public EndNode visitEndNode(EndNode node, Void unused) {
41+
EndNode result = new EndNode(node.getText());
42+
for (SqlNode child : node.getChildren()) {
43+
result.appendNode(child.accept(this, unused));
44+
}
45+
return result;
46+
}
47+
}
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.seasar.doma.internal.jdbc.dialect;
22

3-
import org.seasar.doma.internal.jdbc.sql.SimpleSqlNodeVisitor;
43
import org.seasar.doma.internal.jdbc.sql.node.AnonymousNode;
54
import org.seasar.doma.jdbc.SqlNode;
65

7-
public class StandardCountCalculatingTransformer extends SimpleSqlNodeVisitor<SqlNode, Void> {
6+
public class StandardCountCalculatingTransformer extends AbstractTransformer {
87

98
protected boolean processed;
109

@@ -15,9 +14,4 @@ public SqlNode transform(SqlNode sqlNode) {
1514
}
1615
return result;
1716
}
18-
19-
@Override
20-
protected SqlNode defaultAction(SqlNode node, Void p) {
21-
return node;
22-
}
2317
}

doma-core/src/main/java/org/seasar/doma/internal/jdbc/dialect/StandardCountGettingTransformer.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package org.seasar.doma.internal.jdbc.dialect;
22

3-
import org.seasar.doma.internal.jdbc.sql.SimpleSqlNodeVisitor;
43
import org.seasar.doma.internal.jdbc.sql.node.AnonymousNode;
54
import org.seasar.doma.internal.jdbc.sql.node.FragmentNode;
65
import org.seasar.doma.internal.jdbc.sql.node.FromClauseNode;
76
import org.seasar.doma.internal.jdbc.sql.node.SelectClauseNode;
87
import org.seasar.doma.internal.jdbc.sql.node.SelectStatementNode;
98
import org.seasar.doma.jdbc.SqlNode;
109

11-
public class StandardCountGettingTransformer extends SimpleSqlNodeVisitor<SqlNode, Void> {
10+
public class StandardCountGettingTransformer extends AbstractTransformer {
1211

1312
protected boolean processed;
1413

@@ -47,9 +46,4 @@ public SqlNode visitSelectStatementNode(SelectStatementNode node, Void p) {
4746
result.setOptionClauseNode(node.getOptionClauseNode());
4847
return result;
4948
}
50-
51-
@Override
52-
public SqlNode defaultAction(SqlNode node, Void p) {
53-
return node;
54-
}
5549
}

doma-core/src/main/java/org/seasar/doma/internal/jdbc/dialect/StandardForUpdateTransformer.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
import static org.seasar.doma.internal.util.AssertionUtil.assertNotNull;
44

5-
import org.seasar.doma.internal.jdbc.sql.SimpleSqlNodeVisitor;
65
import org.seasar.doma.internal.jdbc.sql.node.AnonymousNode;
76
import org.seasar.doma.jdbc.SelectForUpdateType;
87
import org.seasar.doma.jdbc.SqlNode;
98

10-
public class StandardForUpdateTransformer extends SimpleSqlNodeVisitor<SqlNode, Void> {
9+
public class StandardForUpdateTransformer extends AbstractTransformer {
1110

1211
protected final SelectForUpdateType forUpdateType;
1312

@@ -32,9 +31,4 @@ public SqlNode transform(SqlNode sqlNode) {
3231
}
3332
return result;
3433
}
35-
36-
@Override
37-
protected SqlNode defaultAction(SqlNode node, Void p) {
38-
return node;
39-
}
4034
}

doma-core/src/main/java/org/seasar/doma/internal/jdbc/dialect/StandardPagingTransformer.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.seasar.doma.jdbc.SqlNode;
1111
import org.seasar.doma.message.Message;
1212

13-
public class StandardPagingTransformer extends SimpleSqlNodeVisitor<SqlNode, Void> {
13+
public class StandardPagingTransformer extends AbstractTransformer {
1414

1515
private final AliasReplacer replacer = new AliasReplacer();
1616

@@ -90,11 +90,6 @@ public SqlNode visitSelectStatementNode(SelectStatementNode node, Void p) {
9090
return result;
9191
}
9292

93-
@Override
94-
protected SqlNode defaultAction(SqlNode node, Void p) {
95-
return node;
96-
}
97-
9893
protected static class AliasReplacer extends SimpleSqlNodeVisitor<SqlNode, Void> {
9994

10095
@Override

doma-core/src/test/java/org/seasar/doma/internal/jdbc/dialect/PostgresPagingTransformerTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
59
import java.util.function.Function;
610
import org.junit.jupiter.api.Test;
11+
import org.seasar.doma.internal.expr.ExpressionEvaluator;
12+
import org.seasar.doma.internal.expr.Value;
713
import org.seasar.doma.internal.jdbc.mock.MockConfig;
814
import org.seasar.doma.internal.jdbc.sql.NodePreparedSqlBuilder;
915
import org.seasar.doma.internal.jdbc.sql.SqlParser;
16+
import org.seasar.doma.jdbc.Config;
1017
import org.seasar.doma.jdbc.PreparedSql;
1118
import org.seasar.doma.jdbc.SqlKind;
19+
import org.seasar.doma.jdbc.SqlLogType;
1220
import org.seasar.doma.jdbc.SqlNode;
1321

1422
public class PostgresPagingTransformerTest {
@@ -60,4 +68,38 @@ public void testLimitOnly() {
6068
PreparedSql sql = sqlBuilder.build(sqlNode, Function.identity());
6169
assertEquals(expected, sql.getRawSql());
6270
}
71+
72+
@Test
73+
public void testOffsetLimit_after_ForBlock() {
74+
String expected = "with fuga as (select * from hoge) select * from fuga limit 10 offset 5";
75+
PostgresPagingTransformer transformer = new PostgresPagingTransformer(5, 10);
76+
SqlParser parser = new SqlParser("/*%for each : list*//*#each*//*%end*/ select * from fuga");
77+
SqlNode originalSqlNode = parser.parse();
78+
SqlNode sqlNode = transformer.transform(originalSqlNode);
79+
Config config = new MockConfig();
80+
Map<String, Value> map = new HashMap<>();
81+
map.put(
82+
"list",
83+
new Value(List.class, Collections.singletonList("with fuga as (select * from hoge)")));
84+
ExpressionEvaluator evaluator =
85+
new ExpressionEvaluator(
86+
map, config.getDialect().getExpressionFunctions(), config.getClassHelper());
87+
NodePreparedSqlBuilder sqlBuilder =
88+
new NodePreparedSqlBuilder(config, SqlKind.SELECT, "dummyPath", evaluator, SqlLogType.RAW);
89+
PreparedSql sql = sqlBuilder.build(sqlNode, Function.identity());
90+
assertEquals(expected, sql.getRawSql());
91+
}
92+
93+
@Test
94+
public void testOffsetLimit_after_IfBlock() {
95+
String expected = "with fuga as (select * from hoge) select * from fuga limit 10 offset 5";
96+
PostgresPagingTransformer transformer = new PostgresPagingTransformer(5, 10);
97+
SqlParser parser =
98+
new SqlParser("/*%if true*/with fuga as (select * from hoge)/*%end*/ select * from fuga");
99+
SqlNode sqlNode = transformer.transform(parser.parse());
100+
NodePreparedSqlBuilder sqlBuilder =
101+
new NodePreparedSqlBuilder(new MockConfig(), SqlKind.SELECT, "dummyPath");
102+
PreparedSql sql = sqlBuilder.build(sqlNode, Function.identity());
103+
assertEquals(expected, sql.getRawSql());
104+
}
63105
}

0 commit comments

Comments
 (0)