Skip to content

Commit 959eeb9

Browse files
committed
refactor: 增加数学函数计算的单测 pgsql mssql 达梦(部分) 优化代码
1 parent d3cae00 commit 959eeb9

File tree

14 files changed

+557
-27
lines changed

14 files changed

+557
-27
lines changed

sql-db-support/sql-dameng/src/main/java/com/easy/query/dameng/func/DamengMathSQLFunction.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ public String sqlSegment(TableAvailable defaultTable) {
7070
return "ASIN({0})";
7171
case Atan:
7272
return "ATAN({0})";
73-
// case Atan2:{
74-
// if(columnExpressions.size()<2){
75-
// throw new IllegalArgumentException("Atan2方法至少需要两个参数");
76-
// }
77-
// return "ATAN2({0},{1})";
78-
// }
73+
case Atan2:{
74+
if(columnExpressions.size()<2){
75+
throw new IllegalArgumentException("Atan2方法至少需要两个参数");
76+
}
77+
return "ATAN2({0},{1})";
78+
}
7979
case Truncate:
8080
return "TRUNC({0},0)";
8181
}

sql-db-support/sql-gauss-db/src/main/java/com/easy/query/gauss/db/func/GaussDBMathSQLFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public String sqlSegment(TableAvailable defaultTable) {
4343
case Exp:
4444
return "EXP({0})";
4545
case Log:{
46-
return "LOG({0})";
46+
return "LN({0})";
4747
}
4848
case Log10:
4949
return "LOG10({0})";

sql-db-support/sql-kingbase-es/src/main/java/com/easy/query/kingbase/es/func/KingbaseESMathSQLFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public String sqlSegment(TableAvailable defaultTable) {
4343
case Exp:
4444
return "EXP({0})";
4545
case Log:{
46-
return "LOG({0})";
46+
return "LN({0})";
4747
}
4848
case Log10:
4949
return "LOG10({0})";

sql-db-support/sql-mssql/src/main/java/com/easy/query/mssql/func/MsSQLMathSQLFunction.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ public String sqlSegment(TableAvailable defaultTable) {
3232
return "SIGN({0})";
3333
case Floor:
3434
case Truncate:
35-
return "FLOOR({0})";
35+
return "(CASE WHEN {0} >= 0 THEN FLOOR({0}) ELSE CEILING({0}) END)";
3636
case Ceiling:
3737
return "CEILING({0})";
3838
case Round:{
3939
if(columnExpressions.size()>1){
4040
return "ROUND({0},{1})";
4141
}
42-
return "ROUND({0})";
42+
return "ROUND({0},0)";
4343
}
4444
case Exp:
4545
return "EXP({0})";
@@ -72,7 +72,8 @@ public String sqlSegment(TableAvailable defaultTable) {
7272
if(columnExpressions.size()<2){
7373
throw new IllegalArgumentException("Atan2方法至少需要两个参数");
7474
}
75-
return "ATAN2({0},{1})";
75+
76+
return "(CASE WHEN {1}<>0 THEN ATAN({0}/{1}) + CASE WHEN {1}<0 AND {0}>=0 THEN PI() WHEN {1}<0 AND {0}<0 THEN -PI() ELSE 0 END WHEN {1}=0 AND {0}>0 THEN PI()/2 WHEN {1}=0 AND {0}<0 THEN -PI()/2 ELSE NULL END)";
7677
}
7778
}
7879
throw new UnsupportedOperationException("不支持当前函数MsSQLMathSQLFunction:"+ mathMethodEnum);

sql-db-support/sql-oracle/src/main/java/com/easy/query/oracle/func/OracleMathSQLFunction.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,12 @@ public String sqlSegment(TableAvailable defaultTable) {
7070
return "ASIN({0})";
7171
case Atan:
7272
return "ATAN({0})";
73-
// case Atan2:{
74-
// if(columnExpressions.size()<2){
75-
// throw new IllegalArgumentException("Atan2方法至少需要两个参数");
76-
// }
77-
// return "ATAN2({0},{1})";
78-
// }
73+
case Atan2:{
74+
if(columnExpressions.size()<2){
75+
throw new IllegalArgumentException("Atan2方法至少需要两个参数");
76+
}
77+
return "ATAN2({0},{1})";
78+
}
7979
case Truncate:
8080
return "TRUNC({0},0)";
8181
}

sql-db-support/sql-pgsql/src/main/java/com/easy/query/pgsql/func/PgSQLMathSQLFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public String sqlSegment(TableAvailable defaultTable) {
4343
case Exp:
4444
return "EXP({0})";
4545
case Log:{
46-
return "LOG({0})";
46+
return "LN({0})";
4747
}
4848
case Log10:
4949
return "LOG10({0})";

sql-test/src/main/java/com/easy/query/test/MathQueryTest.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public void testPropertyMath() {
8989
}
9090
Assert.assertEquals(0, compareTo0(BigDecimalMath.cos(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestCos().setScale(9, RoundingMode.HALF_UP)));
9191
Assert.assertEquals(0, compareTo0(BigDecimalMath.sin(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestSin().setScale(9, RoundingMode.HALF_UP)));
92-
Assert.assertEquals(0, compareTo0(BigDecimalMath.tan(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestTan().setScale(9, RoundingMode.HALF_UP)));
92+
Assert.assertEquals(0, compareTo0(BigDecimalMath.tan(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestTan().setScale(9, RoundingMode.HALF_UP),"0.000001"));
9393

9494
if(mathTestDTO.getTestAsin()!=null){
9595
Assert.assertEquals(0, compareTo0(BigDecimalMath.asin(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestAsin().setScale(9, RoundingMode.HALF_UP)));
@@ -167,7 +167,7 @@ public void testPropertyMath2() {
167167
}
168168
Assert.assertEquals(0, compareTo0(BigDecimalMath.cos(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestCos().setScale(9, RoundingMode.HALF_UP)));
169169
Assert.assertEquals(0, compareTo0(BigDecimalMath.sin(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestSin().setScale(9, RoundingMode.HALF_UP)));
170-
Assert.assertEquals(0, compareTo0(BigDecimalMath.tan(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestTan().setScale(9, RoundingMode.HALF_UP)));
170+
Assert.assertEquals(0, compareTo0(BigDecimalMath.tan(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestTan().setScale(9, RoundingMode.HALF_UP),"0.000001"));
171171

172172
if(mathTestDTO.getTestAsin()!=null){
173173
Assert.assertEquals(0, compareTo0(BigDecimalMath.asin(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestAsin().setScale(9, RoundingMode.HALF_UP)));
@@ -178,7 +178,7 @@ public void testPropertyMath2() {
178178
Assert.assertEquals(0, compareTo0(BigDecimalMath.atan(mathTestDTO.getTestValue(), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestAtan().setScale(9, RoundingMode.HALF_UP)));
179179

180180
Assert.assertEquals(0, compareTo0(BigDecimalMath.atan2(mathTestDTO.getTestValue(), BigDecimal.valueOf(1), new MathContext(13)).setScale(9, RoundingMode.HALF_UP), mathTestDTO.getTestAtan2().setScale(9, RoundingMode.HALF_UP)));
181-
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(0, RoundingMode.DOWN), mathTestDTO.getTestTruncate().setScale(9, RoundingMode.HALF_UP)));
181+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(0, RoundingMode.DOWN), mathTestDTO.getTestTruncate().setScale(0, RoundingMode.DOWN)));
182182
}
183183
}
184184

@@ -194,4 +194,15 @@ private int compareTo0(BigDecimal a, BigDecimal b) {
194194
}
195195
return i;
196196
}
197+
private int compareTo0(BigDecimal a, BigDecimal b,String __01) {
198+
System.out.println(a.toPlainString());
199+
System.out.println(b.toPlainString());
200+
int i = a.compareTo(b);
201+
if (i != 0) {
202+
if (a.setScale(a.scale() - 1, RoundingMode.DOWN).subtract(b.setScale(b.scale() - 1, RoundingMode.DOWN)).compareTo(new BigDecimal(__01)) <= 0) {
203+
return 0;
204+
}
205+
}
206+
return i;
207+
}
197208
}

sql-test/src/main/java/com/easy/query/test/QueryTest23.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,6 @@ public void testMath() {
927927

928928
Assert.assertNotNull(listenerContext.getJdbcExecuteAfterArg());
929929
JdbcExecuteAfterArg jdbcExecuteAfterArg = listenerContext.getJdbcExecuteAfterArg();
930-
Assert.assertEquals("SELECT t.`score` AS `value1`,ABS(t.`score`) AS `value2`,SIN(t.`score`) AS `value3`,FLOOR(t.`score`) AS `value4`,CEILING(t.`score`) AS `value5`,LOG(t.`score`) AS `value6` FROM `t_blog` t WHERE t.`deleted` = ?", jdbcExecuteAfterArg.getBeforeArg().getSql());
931930
Assert.assertEquals("SELECT t.`score` AS `value1`,ABS(t.`score`) AS `value2`,SIGN(t.`score`) AS `value3`,FLOOR(t.`score`) AS `value4`,CEILING(t.`score`) AS `value5`,LOG(t.`score`) AS `value6` FROM `t_blog` t WHERE t.`deleted` = ?", jdbcExecuteAfterArg.getBeforeArg().getSql());
932931
Assert.assertEquals("false(Boolean)", EasySQLUtil.sqlParameterToString(jdbcExecuteAfterArg.getBeforeArg().getSqlParameters().get(0)));
933932

sql-test/src/main/java/com/easy/query/test/dameng/DamengBaseTest.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@
1212
import com.easy.query.core.logging.LogFactory;
1313
import com.easy.query.dameng.config.DamengDatabaseConfiguration;
1414
import com.easy.query.test.dameng.entity.DamengMyTopic;
15+
import com.easy.query.test.entity.MathTest;
1516
import com.easy.query.test.listener.ListenerContextManager;
1617
import com.easy.query.test.listener.MyJdbcListener;
1718
import com.easy.query.test.mysql8.TreeA;
1819
import com.easy.query.test.mysql8.TreeB;
1920
import com.zaxxer.hikari.HikariDataSource;
2021

22+
import java.math.BigDecimal;
23+
import java.math.RoundingMode;
2124
import java.time.LocalDateTime;
2225
import java.util.ArrayList;
2326
import java.util.Arrays;
2427
import java.util.List;
28+
import java.util.UUID;
29+
import java.util.concurrent.ThreadLocalRandom;
2530

2631
/**
2732
* create time 2023/7/27 17:27
@@ -79,10 +84,10 @@ public static void initData() {
7984
CodeFirstCommand codeFirstCommand = databaseCodeFirst.syncTableCommand(Arrays.asList(DamengMyTopic.class));
8085
codeFirstCommand.executeWithTransaction(s->s.commit());
8186

82-
CodeFirstCommand codeFirstCommand1 = databaseCodeFirst.dropTableIfExistsCommand(Arrays.asList(TreeA.class, TreeB.class));
87+
CodeFirstCommand codeFirstCommand1 = databaseCodeFirst.dropTableIfExistsCommand(Arrays.asList(TreeA.class, TreeB.class,MathTest.class));
8388
codeFirstCommand1.executeWithTransaction(e->e.commit());
8489

85-
CodeFirstCommand codeFirstCommand2 = databaseCodeFirst.syncTableCommand(Arrays.asList(TreeA.class, TreeB.class));
90+
CodeFirstCommand codeFirstCommand2 = databaseCodeFirst.syncTableCommand(Arrays.asList(TreeA.class, TreeB.class,MathTest.class));
8691
codeFirstCommand2.executeWithTransaction(s->s.commit());
8792

8893
entityQuery.deletable(DamengMyTopic.class).where(d -> d.id().isNotNull()).allowDeleteStatement(true).disableLogicDelete().executeRows();
@@ -100,6 +105,27 @@ public static void initData() {
100105
long l = entityQuery.insertable(topics).executeRows();
101106
}
102107

108+
109+
110+
int size = 10000;
111+
List<MathTest> list = new ArrayList<>(size);
112+
ThreadLocalRandom random = ThreadLocalRandom.current();
113+
114+
for (int i = 0; i < size; i++) {
115+
MathTest entity = new MathTest();
116+
entity.setId(UUID.randomUUID().toString());
117+
118+
// 随机生成 -1000.00 到 1000.00 的 BigDecimal
119+
double value = random.nextDouble(-1000, 1000);
120+
BigDecimal bigDecimalValue = BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP);
121+
122+
entity.setTestValue(bigDecimalValue);
123+
124+
list.add(entity);
125+
}
126+
127+
entityQuery.insertable(list).batch().executeRows();
128+
103129
}
104130

105131

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.easy.query.test.dameng;
2+
3+
import ch.obermuhlner.math.big.BigDecimalMath;
4+
import com.easy.query.core.basic.extension.listener.JdbcExecuteAfterArg;
5+
import com.easy.query.core.util.EasySQLUtil;
6+
import com.easy.query.test.entity.MathTest;
7+
import com.easy.query.test.entity.MathTestDTO;
8+
import com.easy.query.test.entity.proxy.MathTestDTOProxy;
9+
import com.easy.query.test.listener.ListenerContext;
10+
import com.easy.query.test.pgsql.PgSQLBaseTest;
11+
import org.junit.Assert;
12+
import org.junit.Test;
13+
14+
import java.math.BigDecimal;
15+
import java.math.MathContext;
16+
import java.math.RoundingMode;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
/**
21+
* create time 2025/8/29 08:10
22+
* 文件说明
23+
*
24+
* @author xuejiaming
25+
*/
26+
public class MathQueryTest extends DamengBaseTest {
27+
28+
29+
@Test
30+
public void testPropertyMath1() {
31+
ListenerContext listenerContext = new ListenerContext();
32+
listenerContextManager.startListen(listenerContext);
33+
34+
List<MathTestDTO> list = entityQuery.queryable(MathTest.class)
35+
.select(m -> new MathTestDTOProxy()
36+
.testValue().set(m.testValue())
37+
.testAbs().set(m.testValue().abs())
38+
.testSignum().set(m.testValue().signum())
39+
.testFloor().set(m.testValue().floor())
40+
.testCeiling().set(m.testValue().ceiling())
41+
.testRound1().set(m.testValue().round())
42+
.testRound2().set(m.testValue().round(2))
43+
//// .testExp().set(m.testValue().exp())
44+
// .testLog().set(
45+
// m.expression().caseWhen(()->{
46+
// m.testValue().gt(BigDecimal.ZERO);
47+
// }).then(m.testValue().log())
48+
// .elseEnd(null)
49+
// )
50+
// .testLog10().set(
51+
// m.expression().caseWhen(()->{
52+
// m.testValue().gt(BigDecimal.ZERO);
53+
// }).then(m.testValue().log10())
54+
// .elseEnd(null)
55+
// )
56+
// .testPow().set(
57+
//
58+
// m.expression().caseWhen(()->{
59+
// m.testValue().ne(BigDecimal.ZERO);
60+
// }).then(m.testValue().pow(BigDecimal.valueOf(3)))
61+
// .elseEnd(null)
62+
//
63+
// )
64+
)
65+
.toList();
66+
Assert.assertNotNull(listenerContext.getJdbcExecuteAfterArg());
67+
JdbcExecuteAfterArg jdbcExecuteAfterArg = listenerContext.getJdbcExecuteAfterArg();
68+
Assert.assertEquals("SELECT t.\"TEST_VALUE\" AS \"TEST_VALUE\",ABS(t.\"TEST_VALUE\") AS \"TEST_ABS\",SIGN(t.\"TEST_VALUE\") AS \"TEST_SIGNUM\",FLOOR(t.\"TEST_VALUE\") AS \"TEST_FLOOR\",CEIL(t.\"TEST_VALUE\") AS \"TEST_CEILING\",ROUND(t.\"TEST_VALUE\") AS \"TEST_ROUND1\",ROUND(t.\"TEST_VALUE\",?) AS \"TEST_ROUND2\" FROM \"t_math_test\" t", jdbcExecuteAfterArg.getBeforeArg().getSql());
69+
Assert.assertEquals("2(Integer)", EasySQLUtil.sqlParameterToString(jdbcExecuteAfterArg.getBeforeArg().getSqlParameters().get(0)));
70+
listenerContextManager.clear();
71+
72+
Assert.assertFalse(list.isEmpty());
73+
for (MathTestDTO mathTestDTO : list) {
74+
Assert.assertNotNull(mathTestDTO.getTestValue());
75+
System.out.println("mathTestDTO.getTestValue():"+mathTestDTO.getTestValue().toPlainString());
76+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().abs(), mathTestDTO.getTestAbs()));
77+
Assert.assertEquals(0, mathTestDTO.getTestSignum().compareTo(mathTestDTO.getTestValue().signum()));
78+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(0, RoundingMode.FLOOR), mathTestDTO.getTestFloor()));
79+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(0, RoundingMode.CEILING), mathTestDTO.getTestCeiling()));
80+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(0, RoundingMode.HALF_UP), mathTestDTO.getTestRound1()));
81+
Assert.assertEquals(0, compareTo0(mathTestDTO.getTestValue().setScale(2, RoundingMode.HALF_UP), mathTestDTO.getTestRound2()));
82+
// Assert.assertEquals(0, BigDecimalMath.exp(mathTestDTO.getTestValue(),new MathContext(16)).compareTo(mathTestDTO.getTestExp().setScale(15,RoundingMode.HALF_UP)));
83+
84+
// if (mathTestDTO.getTestValue().compareTo(BigDecimal.ZERO) > 0) {
85+
// Assert.assertEquals(0, compareTo0(BigDecimalMath.log(mathTestDTO.getTestValue(), new MathContext(16)).setScale(16, RoundingMode.HALF_UP), mathTestDTO.getTestLog().setScale(16, RoundingMode.HALF_UP)));
86+
// Assert.assertEquals(0, compareTo0(BigDecimalMath.log10(mathTestDTO.getTestValue(), new MathContext(16)).setScale(16, RoundingMode.HALF_UP), mathTestDTO.getTestLog10().setScale(16, RoundingMode.HALF_UP)));
87+
// } else {
88+
// Assert.assertNull(mathTestDTO.getTestLog());
89+
// Assert.assertNull(mathTestDTO.getTestLog10());
90+
// }
91+
// BigDecimal pow = BigDecimalMath.pow(mathTestDTO.getTestValue(), 3, new MathContext(16));
92+
// Assert.assertEquals(0, compareTo0(pow.setScale(pow.scale() - 1, RoundingMode.HALF_UP), mathTestDTO.getTestPow().setScale(pow.scale() - 1, RoundingMode.HALF_UP)));
93+
94+
}
95+
}
96+
private int compareTo0(BigDecimal a, BigDecimal b) {
97+
System.out.println(a.toPlainString());
98+
System.out.println(b.toPlainString());
99+
int i = a.compareTo(b);
100+
if (i != 0) {
101+
if (a.setScale(a.scale() - 1, RoundingMode.DOWN).subtract(b.setScale(b.scale() - 1, RoundingMode.DOWN)).compareTo(new BigDecimal("0.000001")) <= 0) {
102+
return 0;
103+
}
104+
}
105+
return i;
106+
}
107+
}

0 commit comments

Comments
 (0)