Skip to content

Commit ce8b4f1

Browse files
committed
fix: 修复复杂sql预编译参数数量可能错误问题
1 parent 6fa333f commit ce8b4f1

File tree

2 files changed

+101
-41
lines changed

2 files changed

+101
-41
lines changed

hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/query/QueryAnalyzerImpl.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import net.sf.jsqlparser.expression.*;
66
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
77
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
8+
import net.sf.jsqlparser.schema.Column;
89
import net.sf.jsqlparser.schema.Table;
910
import net.sf.jsqlparser.statement.select.*;
1011
import net.sf.jsqlparser.statement.values.ValuesStatement;
@@ -325,6 +326,7 @@ public void visit(ValuesList valuesList) {
325326
}
326327
String name = parsePlainName(valuesList.getAlias().getName());
327328
FakeTable view = new FakeTable();
329+
view.setSchema(database.getMetadata().getCurrentSchema());
328330
if (valuesList.getColumnNames() != null) {
329331
//获取会自动创建列
330332
for (String columnName : valuesList.getColumnNames()) {
@@ -483,14 +485,13 @@ public void visit(SelectExpressionItem selectExpressionItem) {
483485
Expression expr = selectExpressionItem.getExpression();
484486
Alias alias = selectExpressionItem.getAlias();
485487

486-
if (!(expr instanceof net.sf.jsqlparser.schema.Column)) {
488+
if (!(expr instanceof net.sf.jsqlparser.schema.Column column)) {
487489
String aliasName = parsePlainName(alias == null ? expr.toString() : alias.getName());
488490
refactorAlias(alias);
489491
select.columnList.add(new ExpressionColumn(aliasName, null, null, selectExpressionItem));
490492

491493
return;
492494
}
493-
net.sf.jsqlparser.schema.Column column = ((net.sf.jsqlparser.schema.Column) expr);
494495

495496
String columnName = parsePlainName(column.getColumnName());
496497

@@ -754,6 +755,14 @@ public void visit(PlainSelect plainSelect) {
754755

755756
initColumns(columns);
756757

758+
if (plainSelect.getSelectItems() != null) {
759+
PrepareStatementVisitor visitor = new PrepareStatementVisitor();
760+
for (SelectItem selectItem : plainSelect.getSelectItems()) {
761+
selectItem.accept(visitor);
762+
}
763+
prefixParameters += visitor.parameterSize;
764+
}
765+
757766
if (plainSelect.getFromItem() != null) {
758767
from.append("FROM ");
759768

@@ -1101,6 +1110,9 @@ public void visit(PlainSelect plainSelect) {
11011110
if (plainSelect.getJoins() != null) {
11021111
for (net.sf.jsqlparser.statement.select.Join join : plainSelect.getJoins()) {
11031112
join.getRightItem().accept(this);
1113+
if (join.getOnExpressions() != null) {
1114+
join.getOnExpressions().forEach(expr -> expr.accept(this));
1115+
}
11041116
}
11051117
}
11061118
if (plainSelect.getSelectItems() != null) {
@@ -1115,6 +1127,16 @@ public void visit(PlainSelect plainSelect) {
11151127
plainSelect.getHaving().accept(this);
11161128
}
11171129

1130+
if (plainSelect.getDistinct() != null && plainSelect.getDistinct().getOnSelectItems() != null) {
1131+
plainSelect.getDistinct().getOnSelectItems().forEach(expr -> expr.accept(this));
1132+
}
1133+
1134+
if (plainSelect.getOrderByElements() != null) {
1135+
for (OrderByElement orderByElement : plainSelect.getOrderByElements()) {
1136+
orderByElement.getExpression().accept(this);
1137+
}
1138+
}
1139+
11181140
if (plainSelect.getGroupBy() != null) {
11191141
for (Expression expression : plainSelect.getGroupBy().getGroupByExpressionList().getExpressions()) {
11201142
expression.accept(this);
@@ -1169,7 +1191,8 @@ public Optional<RDBColumnMetadata> getColumn(String name) {
11691191

11701192
QueryHelperUtils.assertLegalColumn(name);
11711193

1172-
RDBColumnMetadata fake = new RDBColumnMetadata();
1194+
RDBColumnMetadata fake = newColumn();
1195+
fake.setOwner(this);
11731196
fake.setName(name);
11741197
addColumn(fake);
11751198
return Optional.of(fake);

hsweb-commons/hsweb-commons-crud/src/test/java/org/hswebframework/web/crud/query/QueryAnalyzerImplTest.java

Lines changed: 75 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.hswebframework.ezorm.rdb.operator.DatabaseOperator;
66
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
77
import org.hswebframework.web.crud.TestApplication;
8+
import org.junit.Assert;
89
import org.junit.Test;
910
import org.junit.runner.RunWith;
1011
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,23 +22,59 @@ public class QueryAnalyzerImplTest {
2122
private DatabaseOperator database;
2223

2324

25+
@Test
26+
public void testParamCast() {
27+
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
28+
database,
29+
"""
30+
SELECT
31+
to_char(period, ?) AS time,
32+
SUM(count_per_period) OVER (ORDER BY period) AS number
33+
FROM (
34+
SELECT
35+
gs.period AS period,
36+
COUNT(tb.create_time) AS count_per_period
37+
FROM
38+
generate_series(?, ?, ?::interval) AS gs(period)
39+
LEFT JOIN s_test ss ON ss.project_id = ?
40+
LEFT JOIN s_test tb
41+
ON tb.subsystem_id = ss.id
42+
AND tb.thing_type = 'device'
43+
AND to_timestamp(tb.create_time / 1000.0) >= gs.period
44+
AND to_timestamp(tb.create_time / 1000.0) < gs.period + ?::interval
45+
LEFT JOIN s_test ddi ON ddi.id = tb.thing_id
46+
GROUP BY gs.period
47+
) sub
48+
ORDER BY period;
49+
""");
50+
SqlRequest request = analyzer.refactor(
51+
QueryParamEntity
52+
.newQuery()
53+
.getParam(), 1, 2, 3, 4, 5, 6);
54+
55+
System.out.println(request.getSql());
56+
System.out.println(request);
57+
58+
Assert.assertEquals(6, request.getParameters().length);
59+
}
60+
2461
@Test
2562
public void testInject() {
2663
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(database,
2764
"select count(distinct time) t2, \"name\" n from \"s_test\" t");
2865
SqlRequest request = analyzer.refactor(
29-
QueryParamEntity
30-
.newQuery()
31-
.and("name", "123")
32-
.getParam());
66+
QueryParamEntity
67+
.newQuery()
68+
.and("name", "123")
69+
.getParam());
3370

3471
System.out.println(request);
3572

3673
SqlRequest sql = analyzer.refactorCount(
37-
QueryParamEntity
38-
.newQuery()
39-
.and("name", "123")
40-
.getParam());
74+
QueryParamEntity
75+
.newQuery()
76+
.and("name", "123")
77+
.getParam());
4178
System.out.println(sql);
4279

4380
}
@@ -47,7 +84,7 @@ public void testInject() {
4784
public void testUnion() {
4885
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(database,
4986
"select name n from s_test t " +
50-
"union select name n from s_test t");
87+
"union select name n from s_test t");
5188

5289
assertNotNull(analyzer.select().table.alias, "t");
5390
assertNotNull(analyzer.select().table.metadata.getName(), "s_test");
@@ -57,7 +94,7 @@ public void testUnion() {
5794
}
5895

5996
@Test
60-
public void test() {
97+
public void test() {
6198
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(database,
6299
"select name n from s_test t");
63100

@@ -79,10 +116,10 @@ public void testSub() {
79116
assertNotNull(analyzer.select().getColumns().get("n"));
80117

81118
SqlRequest request = analyzer
82-
.refactor(QueryParamEntity
83-
.newQuery()
84-
.where("n", "123")
85-
.getParam());
119+
.refactor(QueryParamEntity
120+
.newQuery()
121+
.where("n", "123")
122+
.getParam());
86123

87124
System.out.println(request);
88125

@@ -97,37 +134,37 @@ public void testSub() {
97134
@Test
98135
public void testJoin() {
99136
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
100-
database,
101-
"select *,t2.c from s_test t " +
102-
"left join (select z.id id, count(1) c from s_test z) t2 on t2.id = t.id");
137+
database,
138+
"select *,t2.c from s_test t " +
139+
"left join (select z.id id, count(1) c from s_test z) t2 on t2.id = t.id");
103140

104141
SqlRequest request = analyzer
105-
.refactor(QueryParamEntity
106-
.of()
107-
.and("t2.c", "is", "xyz"));
142+
.refactor(QueryParamEntity
143+
.of()
144+
.and("t2.c", "is", "xyz"));
108145

109146
System.out.println(request);
110147

111148
}
112149

113150
@Test
114-
public void testPrepare(){
151+
public void testPrepare() {
115152
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
116-
database,
117-
"select * from (select substring(id,9) id from s_test where left(id,1) = ?) t");
153+
database,
154+
"select * from (select substring(id,9) id from s_test where left(id,1) = ?) t");
118155

119156
SqlRequest request = analyzer
120-
.refactor(QueryParamEntity.of(),33);
157+
.refactor(QueryParamEntity.of(), 33);
121158

122159
System.out.println(request);
123160
}
124161

125162
@Test
126-
public void testWith(){
163+
public void testWith() {
127164

128165
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
129-
database,
130-
"WITH RECURSIVE Tree AS (\n" +
166+
database,
167+
"WITH RECURSIVE Tree AS (\n" +
131168
"\n" +
132169
" SELECT id\n" +
133170
" FROM s_test\n" +
@@ -143,63 +180,63 @@ public void testWith(){
143180
"FROM Tree AS t1;");
144181

145182
SqlRequest request = analyzer
146-
.refactor(QueryParamEntity.of().and("id","eq","test"),1);
183+
.refactor(QueryParamEntity.of().and("id", "eq", "test"), 1);
147184

148185
System.out.println(request);
149186
}
150187

151188
@Test
152-
public void testTableFunction(){
189+
public void testTableFunction() {
153190
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
154191
database,
155192
"select t.key from json_each_text('{\"name\":\"test\"}') t");
156193

157194
SqlRequest request = analyzer
158-
.refactor(QueryParamEntity.of().and("key","like","test%"),1);
195+
.refactor(QueryParamEntity.of().and("key", "like", "test%"), 1);
159196
System.out.println(request);
160197
}
161198

162199
@Test
163-
public void testTableFunctionJoin(){
200+
public void testTableFunctionJoin() {
164201
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
165202
database,
166203
"select t1.*,t2.key from s_test t1 left join json_each_text('{\"name\":\"test\"}') t2 on t2.key='test' and t2.value='test1'");
167204

168205
SqlRequest request = analyzer
169-
.refactor(QueryParamEntity.of().and("t2.key","like","test%"),1);
206+
.refactor(QueryParamEntity.of().and("t2.key", "like", "test%"), 1);
170207
System.out.println(request);
171208
}
172209

173210
@Test
174-
public void testValues(){
211+
public void testValues() {
175212
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
176213
database,
177214
"select * from (values (1,2),(3,4)) t(\"a\",b)");
178215

179216
SqlRequest request = analyzer
180-
.refactor(QueryParamEntity.of().and("a","eq",1),1);
217+
.refactor(QueryParamEntity.of().and("a", "eq", 1), 1);
181218
System.out.println(request);
182219
}
183220

184221
@Test
185-
public void testLateralSubSelect(){
222+
public void testLateralSubSelect() {
186223
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
187224
database,
188225
"select * from s_test t, lateral(select * from s_test where id = t.id) t2");
189226

190227
SqlRequest request = analyzer
191-
.refactor(QueryParamEntity.of().and("t2.id","eq","test"),1);
228+
.refactor(QueryParamEntity.of().and("t2.id", "eq", "test"), 1);
192229
System.out.println(request);
193230
}
194231

195232
@Test
196-
public void testParenthesisFrom(){
233+
public void testParenthesisFrom() {
197234
QueryAnalyzerImpl analyzer = new QueryAnalyzerImpl(
198235
database,
199236
"select * from (s_test) t");
200237

201238
SqlRequest request = analyzer
202-
.refactor(QueryParamEntity.of().and("t.id","eq","test"),1);
239+
.refactor(QueryParamEntity.of().and("t.id", "eq", "test"), 1);
203240
System.out.println(request);
204241
}
205242

0 commit comments

Comments
 (0)