Skip to content

Commit d4d289c

Browse files
authored
Add CBRT to the V2 engine (opensearch-project#1081)
* Add CBRT to the V2 engine (#166) Signed-off-by: Margarit Hakobyan <margarith@bitquilltech.com> * Fixes after rebase Signed-off-by: Margarit Hakobyan <margarith@bitquilltech.com> Signed-off-by: Margarit Hakobyan <margarith@bitquilltech.com>
1 parent e280866 commit d4d289c

File tree

7 files changed

+129
-3
lines changed

7 files changed

+129
-3
lines changed

core/src/main/java/org/opensearch/sql/expression/DSL.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ public static FunctionExpression sqrt(Expression... expressions) {
225225
return compile(BuiltinFunctionName.SQRT, expressions);
226226
}
227227

228+
public static FunctionExpression cbrt(Expression... expressions) {
229+
return compile(BuiltinFunctionName.CBRT, expressions);
230+
}
231+
228232
public static FunctionExpression truncate(Expression... expressions) {
229233
return compile(BuiltinFunctionName.TRUNCATE, expressions);
230234
}

core/src/main/java/org/opensearch/sql/expression/function/BuiltinFunctionName.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public enum BuiltinFunctionName {
4141
ROUND(FunctionName.of("round")),
4242
SIGN(FunctionName.of("sign")),
4343
SQRT(FunctionName.of("sqrt")),
44+
CBRT(FunctionName.of("cbrt")),
4445
TRUNCATE(FunctionName.of("truncate")),
4546

4647
ACOS(FunctionName.of("acos")),

core/src/main/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunction.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class MathematicalFunction {
5252
*/
5353
public static void register(BuiltinFunctionRepository repository) {
5454
repository.register(abs());
55+
repository.register(cbrt());
5556
repository.register(ceil());
5657
repository.register(ceiling());
5758
repository.register(conv());
@@ -471,6 +472,20 @@ private static DefaultFunctionResolver sqrt() {
471472
DOUBLE, type)).collect(Collectors.toList()));
472473
}
473474

475+
/**
476+
* Definition of cbrt(x) function.
477+
* Calculate the cube root of a number x
478+
* The supported signature is
479+
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
480+
*/
481+
private static DefaultFunctionResolver cbrt() {
482+
return FunctionDSL.define(BuiltinFunctionName.CBRT.getName(),
483+
ExprCoreType.numberTypes().stream()
484+
.map(type -> FunctionDSL.impl(FunctionDSL.nullMissingHandling(
485+
v -> new ExprDoubleValue(Math.cbrt(v.doubleValue()))),
486+
DOUBLE, type)).collect(Collectors.toList()));
487+
}
488+
474489
/**
475490
* Definition of truncate(x, d) function.
476491
* Returns the number x, truncated to d decimal places

core/src/test/java/org/opensearch/sql/expression/operator/arthmetic/MathematicalFunctionTest.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2327,4 +2327,79 @@ public void tan_missing_value() {
23272327
assertEquals(DOUBLE, tan.type());
23282328
assertTrue(tan.valueOf(valueEnv()).isMissing());
23292329
}
2330+
2331+
/**
2332+
* Test cbrt with int value.
2333+
*/
2334+
@ParameterizedTest(name = "cbrt({0})")
2335+
@ValueSource(ints = {1, 2})
2336+
public void cbrt_int_value(Integer value) {
2337+
FunctionExpression cbrt = DSL.cbrt(DSL.literal(value));
2338+
assertThat(cbrt.valueOf(valueEnv()), allOf(hasType(DOUBLE), hasValue(Math.cbrt(value))));
2339+
assertEquals(String.format("cbrt(%s)", value), cbrt.toString());
2340+
}
2341+
2342+
/**
2343+
* Test cbrt with long value.
2344+
*/
2345+
@ParameterizedTest(name = "cbrt({0})")
2346+
@ValueSource(longs = {1L, 2L})
2347+
public void cbrt_long_value(Long value) {
2348+
FunctionExpression cbrt = DSL.cbrt(DSL.literal(value));
2349+
assertThat(cbrt.valueOf(valueEnv()), allOf(hasType(DOUBLE), hasValue(Math.cbrt(value))));
2350+
assertEquals(String.format("cbrt(%s)", value), cbrt.toString());
2351+
}
2352+
2353+
/**
2354+
* Test cbrt with float value.
2355+
*/
2356+
@ParameterizedTest(name = "cbrt({0})")
2357+
@ValueSource(floats = {1F, 2F})
2358+
public void cbrt_float_value(Float value) {
2359+
FunctionExpression cbrt = DSL.cbrt(DSL.literal(value));
2360+
assertThat(cbrt.valueOf(valueEnv()), allOf(hasType(DOUBLE), hasValue(Math.cbrt(value))));
2361+
assertEquals(String.format("cbrt(%s)", value), cbrt.toString());
2362+
}
2363+
2364+
/**
2365+
* Test cbrt with double value.
2366+
*/
2367+
@ParameterizedTest(name = "cbrt({0})")
2368+
@ValueSource(doubles = {1D, 2D, Double.MAX_VALUE, Double.MIN_VALUE})
2369+
public void cbrt_double_value(Double value) {
2370+
FunctionExpression cbrt = DSL.cbrt(DSL.literal(value));
2371+
assertThat(cbrt.valueOf(valueEnv()), allOf(hasType(DOUBLE), hasValue(Math.cbrt(value))));
2372+
assertEquals(String.format("cbrt(%s)", value), cbrt.toString());
2373+
}
2374+
2375+
/**
2376+
* Test cbrt with negative value.
2377+
*/
2378+
@ParameterizedTest(name = "cbrt({0})")
2379+
@ValueSource(doubles = {-1D, -2D})
2380+
public void cbrt_negative_value(Double value) {
2381+
FunctionExpression cbrt = DSL.cbrt(DSL.literal(value));
2382+
assertThat(cbrt.valueOf(valueEnv()), allOf(hasType(DOUBLE), hasValue(Math.cbrt(value))));
2383+
assertEquals(String.format("cbrt(%s)", value), cbrt.toString());
2384+
}
2385+
2386+
/**
2387+
* Test cbrt with null value.
2388+
*/
2389+
@Test
2390+
public void cbrt_null_value() {
2391+
FunctionExpression cbrt = DSL.cbrt(DSL.ref(INT_TYPE_NULL_VALUE_FIELD, INTEGER));
2392+
assertEquals(DOUBLE, cbrt.type());
2393+
assertTrue(cbrt.valueOf(valueEnv()).isNull());
2394+
}
2395+
2396+
/**
2397+
* Test cbrt with missing value.
2398+
*/
2399+
@Test
2400+
public void cbrt_missing_value() {
2401+
FunctionExpression cbrt = DSL.cbrt(DSL.ref(INT_TYPE_MISSING_VALUE_FIELD, INTEGER));
2402+
assertEquals(DOUBLE, cbrt.type());
2403+
assertTrue(cbrt.valueOf(valueEnv()).isMissing());
2404+
}
23302405
}

docs/user/dql/functions.rst

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,24 @@ CBRT
209209
Description
210210
>>>>>>>>>>>
211211

212-
Specifications:
212+
Usage: CBRT(number) calculates the cube root of a number
213+
214+
Argument type: INTEGER/LONG/FLOAT/DOUBLE
215+
216+
Return type: DOUBLE
213217

214-
1. CBRT(NUMBER T) -> T
218+
(Non-negative) INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
219+
(Negative) INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
220+
221+
Example::
222+
223+
opensearchsql> SELECT CBRT(8), CBRT(9.261), CBRT(-27);
224+
fetched rows / total rows = 1/1
225+
+-----------+---------------+-------------+
226+
| CBRT(8) | CBRT(9.261) | CBRT(-27) |
227+
|-----------+---------------+-------------|
228+
| 2.0 | 2.1 | -3.0 |
229+
+-----------+---------------+-------------+
215230

216231

217232
CEIL

integ-test/src/test/java/org/opensearch/sql/sql/MathematicalFunctionIT.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,20 @@ protected JSONObject executeQuery(String query) throws IOException {
162162
Response response = client().performRequest(request);
163163
return new JSONObject(getResponseBody(response));
164164
}
165+
166+
167+
@Test
168+
public void testCbrt() throws IOException {
169+
JSONObject result = executeQuery("select cbrt(8)");
170+
verifySchema(result, schema("cbrt(8)", "double"));
171+
verifyDataRows(result, rows(2.0));
172+
173+
result = executeQuery("select cbrt(9.261)");
174+
verifySchema(result, schema("cbrt(9.261)", "double"));
175+
verifyDataRows(result, rows(2.1));
176+
177+
result = executeQuery("select cbrt(-27)");
178+
verifySchema(result, schema("cbrt(-27)", "double"));
179+
verifyDataRows(result, rows(-3.0));
180+
}
165181
}

sql/src/main/antlr/OpenSearchSQLParser.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ aggregationFunctionName
383383
;
384384

385385
mathematicalFunctionName
386-
: ABS | CEIL | CEILING | CONV | CRC32 | E | EXP | FLOOR | LN | LOG | LOG10 | LOG2 | MOD | PI | POW | POWER
386+
: ABS | CBRT | CEIL | CEILING | CONV | CRC32 | E | EXP | FLOOR | LN | LOG | LOG10 | LOG2 | MOD | PI | POW | POWER
387387
| RAND | ROUND | SIGN | SQRT | TRUNCATE
388388
| trigonometricFunctionName
389389
;

0 commit comments

Comments
 (0)