Skip to content

Commit e8f512f

Browse files
authored
Add SQL sqrt Function with Tests (#890)
1 parent 032e80e commit e8f512f

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed

engine/src/main/java/com/arcadedb/query/sql/function/DefaultSQLFunctionFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.arcadedb.query.sql.function.math.SQLFunctionEval;
5151
import com.arcadedb.query.sql.function.math.SQLFunctionMax;
5252
import com.arcadedb.query.sql.function.math.SQLFunctionMin;
53+
import com.arcadedb.query.sql.function.math.SQLFunctionSquareRoot;
5354
import com.arcadedb.query.sql.function.math.SQLFunctionSum;
5455
import com.arcadedb.query.sql.function.misc.SQLFunctionCoalesce;
5556
import com.arcadedb.query.sql.function.misc.SQLFunctionCount;
@@ -99,6 +100,7 @@ public DefaultSQLFunctionFactory() {
99100
register(SQLFunctionMax.NAME, SQLFunctionMax.class);
100101
register(SQLFunctionMin.NAME, SQLFunctionMin.class);
101102
register(SQLFunctionSet.NAME, SQLFunctionSet.class);
103+
register(SQLFunctionSquareRoot.NAME, SQLFunctionSquareRoot.class);
102104
register(SQLFunctionSum.NAME, SQLFunctionSum.class);
103105
register(SQLFunctionSysdate.NAME, SQLFunctionSysdate.class);
104106
register(SQLFunctionUnionAll.NAME, SQLFunctionUnionAll.class);
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright © 2021-present Arcade Data Ltd ([email protected])
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+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
17+
* SPDX-License-Identifier: Apache-2.0
18+
*/
19+
package com.arcadedb.query.sql.function.math;
20+
21+
import com.arcadedb.database.Identifiable;
22+
import com.arcadedb.query.sql.executor.CommandContext;
23+
24+
import java.math.*;
25+
import java.time.*;
26+
27+
public class SQLFunctionSquareRoot extends SQLFunctionMathAbstract {
28+
public static final String NAME = "sqrt";
29+
private Object result;
30+
31+
public SQLFunctionSquareRoot() {
32+
super(NAME);
33+
}
34+
35+
public Object execute(final Object iThis, final Identifiable iRecord, final Object iCurrentResult, final Object[] iParams, final CommandContext iContext) {
36+
final Object inputValue = iParams[0];
37+
38+
if (inputValue == null) {
39+
result = null;
40+
} else if (inputValue instanceof Number && ((Number) inputValue).doubleValue() < 0.0) {
41+
result = null;
42+
} else if (inputValue instanceof BigDecimal) {
43+
result = ((BigDecimal) inputValue).sqrt(new MathContext(10));
44+
} else if (inputValue instanceof BigInteger) {
45+
result = ((BigInteger) inputValue).sqrt();
46+
} else if (inputValue instanceof Integer) {
47+
result = (int) Math.sqrt((Integer) inputValue);
48+
} else if (inputValue instanceof Long) {
49+
result = (new Double ((int) Math.sqrt((Long) inputValue))).longValue();
50+
} else if (inputValue instanceof Short) {
51+
result = (new Double (Math.sqrt((Short) inputValue))).shortValue();
52+
} else if (inputValue instanceof Double) {
53+
result = Math.sqrt((Double) inputValue);
54+
} else if (inputValue instanceof Float) {
55+
result = (new Double(Math.sqrt((Float) inputValue))).floatValue();
56+
} else if (inputValue instanceof Duration) {
57+
final int seconds = ((Duration) inputValue).toSecondsPart();
58+
final long nanos = ((Duration) inputValue).toNanosPart();
59+
if (seconds < 0 && nanos < 0)
60+
result = null;
61+
else {
62+
result = Duration.ofSeconds((int) Math.sqrt(seconds), (long) Math.sqrt(nanos));
63+
}
64+
} else {
65+
throw new IllegalArgumentException("Argument to square root must be a number.");
66+
}
67+
68+
return getResult();
69+
}
70+
71+
public boolean aggregateResults() {
72+
return false;
73+
}
74+
75+
public String getSyntax() {
76+
return "sqrt(<number>)";
77+
}
78+
79+
@Override
80+
public Object getResult() {
81+
return result;
82+
}
83+
}
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/*
2+
* Copyright © 2021-present Arcade Data Ltd ([email protected])
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+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
17+
* SPDX-License-Identifier: Apache-2.0
18+
*/
19+
package com.arcadedb.query.sql.functions.math;
20+
21+
import com.arcadedb.TestHelper;
22+
import com.arcadedb.query.sql.executor.ResultSet;
23+
import com.arcadedb.query.sql.function.math.SQLFunctionSquareRoot;
24+
import org.junit.jupiter.api.Assertions;
25+
import org.junit.jupiter.api.BeforeEach;
26+
import org.junit.jupiter.api.Test;
27+
28+
import java.math.*;
29+
30+
import static org.junit.jupiter.api.Assertions.assertEquals;
31+
import static org.junit.jupiter.api.Assertions.assertNull;
32+
import static org.junit.jupiter.api.Assertions.assertTrue;
33+
34+
public class SQLFunctionSquareRootTest {
35+
36+
private SQLFunctionSquareRoot function;
37+
38+
@BeforeEach
39+
public void setup() {
40+
function = new SQLFunctionSquareRoot();
41+
}
42+
43+
@Test
44+
public void testEmpty() {
45+
final Object result = function.getResult();
46+
assertNull(result);
47+
}
48+
49+
@Test
50+
public void testNull() {
51+
function.execute(null, null, null, new Object[]{null}, null);
52+
final Object result = function.getResult();
53+
assertNull(result);
54+
}
55+
56+
@Test
57+
public void testPositiveInteger() {
58+
function.execute(null, null, null, new Object[]{4}, null);
59+
final Object result = function.getResult();
60+
assertTrue(result instanceof Integer);
61+
assertEquals(result, 2);
62+
}
63+
64+
@Test
65+
public void testNegativeInteger() {
66+
function.execute(null, null, null, new Object[]{-4}, null);
67+
final Object result = function.getResult();
68+
assertEquals(result, null);
69+
}
70+
71+
@Test
72+
public void testPositiveLong() {
73+
function.execute(null, null, null, new Object[]{4L}, null);
74+
final Object result = function.getResult();
75+
assertTrue(result instanceof Long);
76+
assertEquals(result, 2L);
77+
}
78+
79+
@Test
80+
public void testNegativeLong() {
81+
function.execute(null, null, null, new Object[]{-4L}, null);
82+
final Object result = function.getResult();
83+
assertEquals(result, null);
84+
}
85+
86+
@Test
87+
public void testPositiveShort() {
88+
function.execute(null, null, null, new Object[]{(short) 4}, null);
89+
final Object result = function.getResult();
90+
assertTrue(result instanceof Short);
91+
assertEquals(result, (short) 2);
92+
}
93+
94+
@Test
95+
public void testNegativeShort() {
96+
function.execute(null, null, null, new Object[]{(short) -4}, null);
97+
final Object result = function.getResult();
98+
assertEquals(result, null);
99+
}
100+
101+
@Test
102+
public void testPositiveDouble() {
103+
function.execute(null, null, null, new Object[]{4.0D}, null);
104+
final Object result = function.getResult();
105+
assertTrue(result instanceof Double);
106+
assertEquals(result, 2.0D);
107+
}
108+
109+
@Test
110+
public void testNegativeDouble() {
111+
function.execute(null, null, null, new Object[]{-4.0D}, null);
112+
final Object result = function.getResult();
113+
assertEquals(result, null);
114+
}
115+
116+
@Test
117+
public void testPositiveFloat() {
118+
function.execute(null, null, null, new Object[]{4.0F}, null);
119+
final Object result = function.getResult();
120+
assertTrue(result instanceof Float);
121+
assertEquals(result, 2.0F);
122+
}
123+
124+
@Test
125+
public void testNegativeFloat() {
126+
function.execute(null, null, null, new Object[]{-4.0F}, null);
127+
final Object result = function.getResult();
128+
assertEquals(result, null);
129+
}
130+
131+
@Test
132+
public void testPositiveBigDecimal() {
133+
function.execute(null, null, null, new Object[]{new BigDecimal("4.0")}, null);
134+
final Object result = function.getResult();
135+
assertTrue(result instanceof BigDecimal);
136+
assertEquals(result, new BigDecimal("2"));
137+
}
138+
139+
@Test
140+
public void testNegativeBigDecimal() {
141+
function.execute(null, null, null, new Object[]{BigDecimal.valueOf(-4.0D)}, null);
142+
final Object result = function.getResult();
143+
assertEquals(result, null);
144+
}
145+
146+
@Test
147+
public void testPositiveBigInteger() {
148+
function.execute(null, null, null, new Object[]{new BigInteger("4")}, null);
149+
final Object result = function.getResult();
150+
assertTrue(result instanceof BigInteger);
151+
assertEquals(result, new BigInteger("2"));
152+
}
153+
154+
@Test
155+
public void testNegativeBigInteger() {
156+
function.execute(null, null, null, new Object[]{new BigInteger("-4")}, null);
157+
final Object result = function.getResult();
158+
assertEquals(result, null);
159+
}
160+
161+
@Test
162+
public void testNonNumber() {
163+
try {
164+
function.execute(null, null, null, new Object[]{"abc"}, null);
165+
Assertions.fail("Expected IllegalArgumentException");
166+
} catch (final IllegalArgumentException e) {
167+
// OK
168+
}
169+
}
170+
171+
@Test
172+
public void testFromQuery() throws Exception {
173+
TestHelper.executeInNewDatabase("./target/databases/testSqrtFunction", (db) -> {
174+
final ResultSet result = db.query("sql", "select sqrt(4.0) as sqrt");
175+
assertEquals(2.0F, ((Number) result.next().getProperty("sqrt")).floatValue());
176+
});
177+
}
178+
}

0 commit comments

Comments
 (0)