Skip to content

Commit 9ac9ac0

Browse files
adds array support to COALESCE function
1 parent ffbeb82 commit 9ac9ac0

File tree

3 files changed

+60
-34
lines changed

3 files changed

+60
-34
lines changed

docs/references/functions.md

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ Available through the _ExpressionConfiguration.StandardFunctionsDictionary_ cons
1111

1212
### Basic Functions
1313

14-
| Name | Description |
15-
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------|
16-
| [ABS](#abs) | Absolute (non-negative) value |
17-
| [AVERAGE](#average) | Returns the average (arithmetic mean) of all parameters. If a parameter is of type _ARRAY_, the average of all elements is calculated. |
18-
| [CEILING](#ceiling) | Rounds the given value to the nearest integer using the rounding mode CEILING |
19-
| [COALESCE](#coalesce) | Returns the first non-null parameter, or NULL if all parameters are null |
20-
| [FACT](#fact) | Calculates the factorial of a base value |
21-
| [FLOOR](#floor) | Rounds the given value to the nearest integer using the rounding mode FLOOR |
22-
| [IF](#if) | Conditional evaluation function. Returns one value or another, depending on a given condition. |
23-
| [LOG](#log) | The natural logarithm (base e) of a value |
24-
| [LOG10](#log10) | The base 10 logarithm of a value |
25-
| [MAX](#max) | Returns the maximum value of all parameters. If a parameter is of type _ARRAY_, the maximum of all elements is calculated. |
26-
| [MIN](#min) | Returns the minimum value of all parameters. If a parameter is of type _ARRAY_, the minimum of all elements is calculated. |
27-
| [NOT](#not) | Boolean negation, implemented as a function (for compatibility) |
28-
| [RANDOM](#random) | Produces a random value between 0 and 1 |
29-
| [ROUND](#round) | Rounds the given value to the specified scale, using the current rounding mode |
30-
| [SQRT](#sqrt) | Returns the square root of a given number |
31-
| [SUM](#sum) | Returns the sum of all parameters. If a parameter is of type _ARRAY_, the sum of all elements is calculated. |
32-
| [SWITCH](#switch) | Returns the result correponding to the first matching value in the specified expression or an optional default value if no match found. |
14+
| Name | Description |
15+
|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
16+
| [ABS](#abs) | Absolute (non-negative) value |
17+
| [AVERAGE](#average) | Returns the average (arithmetic mean) of all parameters. If a parameter is of type _ARRAY_, the average of all elements is calculated. |
18+
| [CEILING](#ceiling) | Rounds the given value to the nearest integer using the rounding mode CEILING |
19+
| [COALESCE](#coalesce) | Returns the first non-null parameter, or NULL if all parameters are null. If a parameter is of type ARRAY, returns the first non-null element. |
20+
| [FACT](#fact) | Calculates the factorial of a base value |
21+
| [FLOOR](#floor) | Rounds the given value to the nearest integer using the rounding mode FLOOR |
22+
| [IF](#if) | Conditional evaluation function. Returns one value or another, depending on a given condition. |
23+
| [LOG](#log) | The natural logarithm (base e) of a value |
24+
| [LOG10](#log10) | The base 10 logarithm of a value |
25+
| [MAX](#max) | Returns the maximum value of all parameters. If a parameter is of type _ARRAY_, the maximum of all elements is calculated. |
26+
| [MIN](#min) | Returns the minimum value of all parameters. If a parameter is of type _ARRAY_, the minimum of all elements is calculated. |
27+
| [NOT](#not) | Boolean negation, implemented as a function (for compatibility) |
28+
| [RANDOM](#random) | Produces a random value between 0 and 1 |
29+
| [ROUND](#round) | Rounds the given value to the specified scale, using the current rounding mode |
30+
| [SQRT](#sqrt) | Returns the square root of a given number |
31+
| [SUM](#sum) | Returns the sum of all parameters. If a parameter is of type _ARRAY_, the sum of all elements is calculated. |
32+
| [SWITCH](#switch) | Returns the result correponding to the first matching value in the specified expression or an optional default value if no match found. |
3333

3434
### String Functions
3535

@@ -225,27 +225,30 @@ COALESCE(value, [...])
225225

226226
### Parameters
227227

228-
| Name | Description |
229-
|------------|-------------------------------------|
230-
| value, ... | One or more values to be evaluated. |
228+
| Name | Description |
229+
|------------|----------------------------------------------------------|
230+
| value, ... | One or more values or arrays from which to be evaluated. |
231231

232232
### Examples
233233

234234
Consider the following variables:
235235

236-
| Name | Value |
237-
|----------|-----------|
238-
| `a` | `null` |
239-
| `b` | `"hello"` |
240-
| `c` | `42` |
236+
| Name | Value |
237+
|------------|---------------|
238+
| `a` | `null` |
239+
| `b` | `"hello"` |
240+
| `c` | `42` |
241+
| `numbers` | `[null, 8, 5]`|
241242

242243
And the following expressions:
243244

244-
| Expression | Result |
245-
|-----------------------|-----------|
246-
| `COALESCE(a, b, c)` | `"hello"` |
247-
| `COALESCE(a, null, c)`| `42` |
248-
| `COALESCE(a, null)` | `null` |
245+
| Expression | Result |
246+
|---------------------------|-----------|
247+
| `COALESCE(a, b, c)` | `"hello"` |
248+
| `COALESCE(a, null, c)` | `42` |
249+
| `COALESCE(a, null)` | `null` |
250+
| `COALESCE(numbers)` | `8` |
251+
| `COALESCE(a, numbers, b)` | `8` |
249252

250253
🔝 [Back to Basic Functions](#basic-functions) | 🔝 [Back to top](#top)
251254

src/main/java/com/ezylang/evalex/functions/basic/CoalesceFunction.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,16 @@ public class CoalesceFunction extends AbstractFunction {
3131
public EvaluationValue evaluate(
3232
Expression expression, Token functionToken, EvaluationValue... parameterValues) {
3333
for (EvaluationValue parameter : parameterValues) {
34-
if (!parameter.isNullValue()) {
35-
return parameter;
34+
if (parameter.isArrayValue()) {
35+
for (EvaluationValue element : parameter.getArrayValue()) {
36+
if (!element.isNullValue()) {
37+
return element;
38+
}
39+
}
40+
} else {
41+
if (!parameter.isNullValue()) {
42+
return parameter;
43+
}
3644
}
3745
}
3846
return EvaluationValue.NULL_VALUE;

src/test/java/com/ezylang/evalex/functions/basic/BasicFunctionsTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.ezylang.evalex.parser.Token.TokenType;
3030
import java.math.MathContext;
3131
import java.math.RoundingMode;
32+
import java.util.Arrays;
3233
import org.junit.jupiter.api.Test;
3334
import org.junit.jupiter.params.ParameterizedTest;
3435
import org.junit.jupiter.params.provider.CsvSource;
@@ -388,6 +389,20 @@ void testCoalesce(String expression, String expectedResult)
388389
}
389390
}
390391

392+
@Test
393+
void testCoalesceWithArray()
394+
throws EvaluationException, ParseException {
395+
EvaluationValue evaluationValue = new Expression("COALESCE(A, B, C)",
396+
TestConfigurationProvider.StandardConfigurationWithAdditionalTestOperators)
397+
.with("A", null)
398+
.with("B", Arrays.asList(null, "8", null, null))
399+
.with("C", "7")
400+
.evaluate();
401+
402+
assertThat(evaluationValue.isNullValue()).isFalse();
403+
assertThat(evaluationValue.getStringValue()).isEqualTo("8");
404+
}
405+
391406
@ParameterizedTest
392407
@CsvSource(
393408
delimiter = ':',

0 commit comments

Comments
 (0)