Skip to content

Commit

Permalink
Add support for long value return for CEIL, CEILING and FLOOR math fu…
Browse files Browse the repository at this point in the history
…nctions (#1205)

* Added long fix for CEIL, CEILING and FLOOR functions using LONG instead of INT for RETURN.

Signed-off-by: MitchellGale-BitQuill <[email protected]>

* Revert changes to JDBCConnection.java.

Signed-off-by: MitchellGale-BitQuill <[email protected]>

* Addressed PR comments.

Signed-off-by: MitchellGale-BitQuill <[email protected]>

* Made fixes to rst files.

Signed-off-by: MitchellGale-BitQuill <[email protected]>

* Simplify docs according to PR feedback.

Signed-off-by: Yury-Fridlyand <[email protected]>

Signed-off-by: MitchellGale-BitQuill <[email protected]>
Signed-off-by: Yury-Fridlyand <[email protected]>
Co-authored-by: Yury-Fridlyand <[email protected]>
(cherry picked from commit dc5578a)
  • Loading branch information
MitchellGale authored and github-actions[bot] committed Jan 9, 2023
1 parent 7fa65e7 commit 6bd5de7
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,16 @@ private static DefaultFunctionResolver abs() {
private static DefaultFunctionResolver ceil() {
return FunctionDSL.define(BuiltinFunctionName.CEIL.getName(),
FunctionDSL.impl(
FunctionDSL.nullMissingHandling(v -> new ExprIntegerValue(Math.ceil(v.doubleValue()))),
INTEGER, DOUBLE)
FunctionDSL.nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))),
LONG, DOUBLE)
);
}

private static DefaultFunctionResolver ceiling() {
return FunctionDSL.define(BuiltinFunctionName.CEILING.getName(),
FunctionDSL.impl(
FunctionDSL.nullMissingHandling(v -> new ExprIntegerValue(Math.ceil(v.doubleValue()))),
INTEGER, DOUBLE)
FunctionDSL.nullMissingHandling(v -> new ExprLongValue(Math.ceil(v.doubleValue()))),
LONG, DOUBLE)
);
}

Expand Down Expand Up @@ -204,8 +204,8 @@ private static DefaultFunctionResolver exp() {
private static DefaultFunctionResolver floor() {
return FunctionDSL.define(BuiltinFunctionName.FLOOR.getName(),
FunctionDSL.impl(
FunctionDSL.nullMissingHandling(v -> new ExprIntegerValue(Math.floor(v.doubleValue()))),
INTEGER, DOUBLE)
FunctionDSL.nullMissingHandling(v -> new ExprLongValue(Math.floor(v.doubleValue()))),
LONG, DOUBLE)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,13 @@ public void ceil_int_value(Integer value) {
FunctionExpression ceil = DSL.ceil(DSL.literal(value));
assertThat(
ceil.valueOf(valueEnv()),
allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value), ceil.toString());
allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value.toString()), ceil.toString());

FunctionExpression ceiling = DSL.ceiling(DSL.literal(value));
assertThat(
ceiling.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value), ceiling.toString());
ceiling.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value.toString()), ceiling.toString());
}

/**
Expand All @@ -208,13 +208,30 @@ public void ceil_int_value(Integer value) {
public void ceil_long_value(Long value) {
FunctionExpression ceil = DSL.ceil(DSL.literal(value));
assertThat(
ceil.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value), ceil.toString());
ceil.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value.toString()), ceil.toString());

FunctionExpression ceiling = DSL.ceiling(DSL.literal(value));
assertThat(
ceiling.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value), ceiling.toString());
ceiling.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value.toString()), ceiling.toString());
}

/**
* Test ceil/ceiling with long value.
*/
@ParameterizedTest(name = "ceil({0})")
@ValueSource(longs = {9223372036854775805L, -9223372036854775805L})
public void ceil_long_value_long(Long value) {
FunctionExpression ceil = DSL.ceil(DSL.literal(value));
assertThat(
ceil.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value.toString()), ceil.toString());

FunctionExpression ceiling = DSL.ceiling(DSL.literal(value));
assertThat(
ceiling.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value.toString()), ceiling.toString());
}

/**
Expand All @@ -225,13 +242,13 @@ public void ceil_long_value(Long value) {
public void ceil_float_value(Float value) {
FunctionExpression ceil = DSL.ceil(DSL.literal(value));
assertThat(
ceil.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value), ceil.toString());
ceil.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value.toString()), ceil.toString());

FunctionExpression ceiling = DSL.ceiling(DSL.literal(value));
assertThat(
ceiling.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value), ceiling.toString());
ceiling.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value.toString()), ceiling.toString());
}

/**
Expand All @@ -242,13 +259,13 @@ public void ceil_float_value(Float value) {
public void ceil_double_value(Double value) {
FunctionExpression ceil = DSL.ceil(DSL.literal(value));
assertThat(
ceil.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value), ceil.toString());
ceil.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceil(%s)", value.toString()), ceil.toString());

FunctionExpression ceiling = DSL.ceiling(DSL.literal(value));
assertThat(
ceiling.valueOf(valueEnv()), allOf(hasType(INTEGER), hasValue((int) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value), ceiling.toString());
ceiling.valueOf(valueEnv()), allOf(hasType(LONG), hasValue((long) Math.ceil(value))));
assertEquals(String.format("ceiling(%s)", value.toString()), ceiling.toString());
}

/**
Expand All @@ -257,11 +274,11 @@ public void ceil_double_value(Double value) {
@Test
public void ceil_null_value() {
FunctionExpression ceil = DSL.ceil(DSL.ref(DOUBLE_TYPE_NULL_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, ceil.type());
assertEquals(LONG, ceil.type());
assertTrue(ceil.valueOf(valueEnv()).isNull());

FunctionExpression ceiling = DSL.ceiling(DSL.ref(DOUBLE_TYPE_NULL_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, ceiling.type());
assertEquals(LONG, ceiling.type());
assertTrue(ceiling.valueOf(valueEnv()).isNull());
}

Expand All @@ -271,11 +288,11 @@ public void ceil_null_value() {
@Test
public void ceil_missing_value() {
FunctionExpression ceil = DSL.ceil(DSL.ref(DOUBLE_TYPE_MISSING_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, ceil.type());
assertEquals(LONG, ceil.type());
assertTrue(ceil.valueOf(valueEnv()).isMissing());

FunctionExpression ceiling = DSL.ceiling(DSL.ref(DOUBLE_TYPE_MISSING_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, ceiling.type());
assertEquals(LONG, ceiling.type());
assertTrue(ceiling.valueOf(valueEnv()).isMissing());
}

Expand Down Expand Up @@ -557,7 +574,7 @@ public void floor_int_value(Integer value) {
FunctionExpression floor = DSL.floor(DSL.literal(value));
assertThat(
floor.valueOf(valueEnv()),
allOf(hasType(INTEGER), hasValue((int) Math.floor(value))));
allOf(hasType(LONG), hasValue((long) Math.floor(value))));
assertEquals(String.format("floor(%s)", value.toString()), floor.toString());
}

Expand All @@ -570,7 +587,7 @@ public void floor_long_value(Long value) {
FunctionExpression floor = DSL.floor(DSL.literal(value));
assertThat(
floor.valueOf(valueEnv()),
allOf(hasType(INTEGER), hasValue((int) Math.floor(value))));
allOf(hasType(LONG), hasValue((long) Math.floor(value))));
assertEquals(String.format("floor(%s)", value.toString()), floor.toString());
}

Expand All @@ -583,7 +600,7 @@ public void floor_float_value(Float value) {
FunctionExpression floor = DSL.floor(DSL.literal(value));
assertThat(
floor.valueOf(valueEnv()),
allOf(hasType(INTEGER), hasValue((int) Math.floor(value))));
allOf(hasType(LONG), hasValue((long) Math.floor(value))));
assertEquals(String.format("floor(%s)", value.toString()), floor.toString());
}

Expand All @@ -596,7 +613,7 @@ public void floor_double_value(Double value) {
FunctionExpression floor = DSL.floor(DSL.literal(value));
assertThat(
floor.valueOf(valueEnv()),
allOf(hasType(INTEGER), hasValue((int) Math.floor(value))));
allOf(hasType(LONG), hasValue((long) Math.floor(value))));
assertEquals(String.format("floor(%s)", value.toString()), floor.toString());
}

Expand All @@ -606,7 +623,7 @@ public void floor_double_value(Double value) {
@Test
public void floor_null_value() {
FunctionExpression floor = DSL.floor(DSL.ref(DOUBLE_TYPE_NULL_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, floor.type());
assertEquals(LONG, floor.type());
assertTrue(floor.valueOf(valueEnv()).isNull());
}

Expand All @@ -616,7 +633,7 @@ public void floor_null_value() {
@Test
public void floor_missing_value() {
FunctionExpression floor = DSL.floor(DSL.ref(DOUBLE_TYPE_MISSING_VALUE_FIELD, DOUBLE));
assertEquals(INTEGER, floor.type());
assertEquals(LONG, floor.type());
assertTrue(floor.valueOf(valueEnv()).isMissing());
}

Expand Down
67 changes: 63 additions & 4 deletions docs/user/dql/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,42 @@ Example::
CEIL
----

An alias for `CEILING`_ function.


CEILING
-------

Description
>>>>>>>>>>>

Specifications:
Usage: CEILING(T) takes the ceiling of value T.

Note: `CEIL`_ and CEILING functions have the same implementation & functionality

Limitation: CEILING only works as expected when IEEE 754 double type displays decimal when stored.

Argument type: INTEGER/LONG/FLOAT/DOUBLE

Return type: LONG

Example::

os> SELECT CEILING(0), CEILING(50.00005), CEILING(-50.00005);
fetched rows / total rows = 1/1
+--------------+---------------------+----------------------+
| CEILING(0) | CEILING(50.00005) | CEILING(-50.00005) |
|--------------+---------------------+----------------------|
| 0 | 51 | -50 |
+--------------+---------------------+----------------------+

1. CEIL(NUMBER T) -> T
os> SELECT CEILING(3147483647.12345), CEILING(113147483647.12345), CEILING(3147483647.00001);
fetched rows / total rows = 1/1
+-----------------------------+-------------------------------+-----------------------------+
| CEILING(3147483647.12345) | CEILING(113147483647.12345) | CEILING(3147483647.00001) |
|-----------------------------+-------------------------------+-----------------------------|
| 3147483648 | 113147483648 | 3147483648 |
+-----------------------------+-------------------------------+-----------------------------+


CONV
Expand Down Expand Up @@ -424,10 +454,39 @@ FLOOR
Description
>>>>>>>>>>>

Specifications:
Usage: FLOOR(T) takes the floor of value T.

Limitation: FLOOR only works as expected when IEEE 754 double type displays decimal when stored.

Argument type: INTEGER/LONG/FLOAT/DOUBLE

Return type: LONG

Example::

1. FLOOR(NUMBER T) -> T
os> SELECT FLOOR(0), FLOOR(50.00005), FLOOR(-50.00005);
fetched rows / total rows = 1/1
+------------+-------------------+--------------------+
| FLOOR(0) | FLOOR(50.00005) | FLOOR(-50.00005) |
|------------+-------------------+--------------------|
| 0 | 50 | -51 |
+------------+-------------------+--------------------+

os> SELECT FLOOR(3147483647.12345), FLOOR(113147483647.12345), FLOOR(3147483647.00001);
fetched rows / total rows = 1/1
+---------------------------+-----------------------------+---------------------------+
| FLOOR(3147483647.12345) | FLOOR(113147483647.12345) | FLOOR(3147483647.00001) |
|---------------------------+-----------------------------+---------------------------|
| 3147483647 | 113147483647 | 3147483647 |
+---------------------------+-----------------------------+---------------------------+

os> SELECT FLOOR(282474973688888.022), FLOOR(9223372036854775807.022), FLOOR(9223372036854775807.0000001);
fetched rows / total rows = 1/1
+------------------------------+----------------------------------+--------------------------------------+
| FLOOR(282474973688888.022) | FLOOR(9223372036854775807.022) | FLOOR(9223372036854775807.0000001) |
|------------------------------+----------------------------------+--------------------------------------|
| 282474973688888 | 9223372036854775807 | 9223372036854775807 |
+------------------------------+----------------------------------+--------------------------------------+

LN
--
Expand Down
69 changes: 52 additions & 17 deletions docs/user/ppl/functions/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,24 +127,42 @@ Example::
CEIL
----

An alias for `CEILING`_ function.


CEILING
-------

Description
>>>>>>>>>>>

Usage: ceil(x) return the smallest integer value this is greater or equal to x.
Usage: CEILING(T) takes the ceiling of value T.

Note: `CEIL`_ and CEILING functions have the same implementation & functionality

Limitation: CEILING only works as expected when IEEE 754 double type displays decimal when stored.

Argument type: INTEGER/LONG/FLOAT/DOUBLE

Return type: INTEGER
Return type: LONG

Example::

os> source=people | eval `CEIL(2.75)` = CEIL(2.75) | fields `CEIL(2.75)`
os> source=people | eval `CEILING(0)` = CEILING(0), `CEILING(50.00005)` = CEILING(50.00005), `CEILING(-50.00005)` = CEILING(-50.00005) | fields `CEILING(0)`, `CEILING(50.00005)`, `CEILING(-50.00005)`
fetched rows / total rows = 1/1
+--------------+
| CEIL(2.75) |
|--------------|
| 3 |
+--------------+
+--------------+---------------------+----------------------+
| CEILING(0) | CEILING(50.00005) | CEILING(-50.00005) |
|--------------+---------------------+----------------------|
| 0 | 51 | -50 |
+--------------+---------------------+----------------------+

os> source=people | eval `CEILING(3147483647.12345)` = CEILING(3147483647.12345), `CEILING(113147483647.12345)` = CEILING(113147483647.12345), `CEILING(3147483647.00001)` = CEILING(3147483647.00001) | fields `CEILING(3147483647.12345)`, `CEILING(113147483647.12345)`, `CEILING(3147483647.00001)`
fetched rows / total rows = 1/1
+-----------------------------+-------------------------------+-----------------------------+
| CEILING(3147483647.12345) | CEILING(113147483647.12345) | CEILING(3147483647.00001) |
|-----------------------------+-------------------------------+-----------------------------|
| 3147483648 | 113147483648 | 3147483648 |
+-----------------------------+-------------------------------+-----------------------------+


CONV
Expand Down Expand Up @@ -310,22 +328,39 @@ FLOOR
Description
>>>>>>>>>>>

Usage: floor(x) return the largest integer value this is smaller or equal to x.
Usage: FLOOR(T) takes the floor of value T.

Argument type: INTEGER/LONG/FLOAT/DOUBLE
Limitation: FLOOR only works as expected when IEEE 754 double type displays decimal when stored.

Return type: INTEGER
Argument type: a: INTEGER/LONG/FLOAT/DOUBLE

Return type: LONG

Example::

os> source=people | eval `FLOOR(2.75)` = FLOOR(2.75) | fields `FLOOR(2.75)`
os> source=people | eval `FLOOR(0)` = FLOOR(0), `FLOOR(50.00005)` = FLOOR(50.00005), `FLOOR(-50.00005)` = FLOOR(-50.00005) | fields `FLOOR(0)`, `FLOOR(50.00005)`, `FLOOR(-50.00005)`
fetched rows / total rows = 1/1
+---------------+
| FLOOR(2.75) |
|---------------|
| 2 |
+---------------+
+------------+-------------------+--------------------+
| FLOOR(0) | FLOOR(50.00005) | FLOOR(-50.00005) |
|------------+-------------------+--------------------|
| 0 | 50 | -51 |
+------------+-------------------+--------------------+

os> source=people | eval `FLOOR(3147483647.12345)` = FLOOR(3147483647.12345), `FLOOR(113147483647.12345)` = FLOOR(113147483647.12345), `FLOOR(3147483647.00001)` = FLOOR(3147483647.00001) | fields `FLOOR(3147483647.12345)`, `FLOOR(113147483647.12345)`, `FLOOR(3147483647.00001)`
fetched rows / total rows = 1/1
+---------------------------+-----------------------------+---------------------------+
| FLOOR(3147483647.12345) | FLOOR(113147483647.12345) | FLOOR(3147483647.00001) |
|---------------------------+-----------------------------+---------------------------|
| 3147483647 | 113147483647 | 3147483647 |
+---------------------------+-----------------------------+---------------------------+

os> source=people | eval `FLOOR(282474973688888.022)` = FLOOR(282474973688888.022), `FLOOR(9223372036854775807.022)` = FLOOR(9223372036854775807.022), `FLOOR(9223372036854775807.0000001)` = FLOOR(9223372036854775807.0000001) | fields `FLOOR(282474973688888.022)`, `FLOOR(9223372036854775807.022)`, `FLOOR(9223372036854775807.0000001)`
fetched rows / total rows = 1/1
+------------------------------+----------------------------------+--------------------------------------+
| FLOOR(282474973688888.022) | FLOOR(9223372036854775807.022) | FLOOR(9223372036854775807.0000001) |
|------------------------------+----------------------------------+--------------------------------------|
| 282474973688888 | 9223372036854775807 | 9223372036854775807 |
+------------------------------+----------------------------------+--------------------------------------+

LN
--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void testCeilWithLongFieldReturnsLong() {
executeJdbcRequest("SELECT CEIL(balance) FROM " + TestsConstants.TEST_INDEX_ACCOUNT +
" ORDER BY balance LIMIT 5");

verifySchema(response, schema("CEIL(balance)", null, "integer"));
verifySchema(response, schema("CEIL(balance)", null, "long"));
}

/*
Expand Down
Loading

0 comments on commit 6bd5de7

Please sign in to comment.