Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions async-query-core/src/main/antlr/OpenSearchPPLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ REPLACE: 'REPLACE';
REVERSE: 'REVERSE';
CAST: 'CAST';
ISEMPTY: 'ISEMPTY';
ISNOTEMPTY: 'ISNOTEMPTY';
ISBLANK: 'ISBLANK';

// JSON TEXT FUNCTIONS
Expand Down
6 changes: 6 additions & 0 deletions async-query-core/src/main/antlr/OpenSearchPPLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ positionFunction
booleanExpression
: booleanFunctionCall # booleanFunctionCallExpr
| isEmptyExpression # isEmptyExpr
| isNotEmptyExpression # isNotEmptyExpr
| valueExpressionList NOT? IN LT_SQR_PRTHS subSearch RT_SQR_PRTHS # inSubqueryExpr
| EXISTS LT_SQR_PRTHS subSearch RT_SQR_PRTHS # existsSubqueryExpr
| cidrMatchFunctionCall # cidrFunctionCallExpr
Expand All @@ -477,6 +478,10 @@ booleanExpression
: (ISEMPTY | ISBLANK) LT_PRTHS functionArg RT_PRTHS
;

isNotEmptyExpression
: ISNOTEMPTY LT_PRTHS functionArg RT_PRTHS
;

caseFunction
: CASE LT_PRTHS logicalExpression COMMA valueExpression (COMMA logicalExpression COMMA valueExpression)* (ELSE valueExpression)? RT_PRTHS
;
Expand Down Expand Up @@ -860,6 +865,7 @@ textFunctionName
| REPLACE
| REVERSE
| ISEMPTY
| ISNOTEMPTY
| ISBLANK
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ public enum BuiltinFunctionName {

IS_PRESENT(FunctionName.of("ispresent")),
IS_EMPTY(FunctionName.of("isempty")),
IS_NOT_EMPTY(FunctionName.of("isnotempty")),
IS_BLANK(FunctionName.of("isblank")),

ROW_NUMBER(FunctionName.of("row_number")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
import static org.opensearch.sql.expression.function.BuiltinFunctionName.INTERNAL_TRANSLATE3;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_BLANK;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_EMPTY;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_NOT_EMPTY;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_NOT_NULL;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_NULL;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.IS_PRESENT;
Expand Down Expand Up @@ -1252,6 +1253,17 @@ void populate() {
builder.makeCall(SqlStdOperatorTable.IS_NULL, arg),
builder.makeCall(SqlStdOperatorTable.IS_EMPTY, arg)),
PPLTypeChecker.family(SqlTypeFamily.ANY));
register(
IS_NOT_EMPTY,
(FunctionImp1)
(builder, arg) ->
builder.makeCall(
SqlStdOperatorTable.NOT,
builder.makeCall(
SqlStdOperatorTable.OR,
builder.makeCall(SqlStdOperatorTable.IS_NULL, arg),
builder.makeCall(SqlStdOperatorTable.IS_EMPTY, arg))),
PPLTypeChecker.family(SqlTypeFamily.ANY));
register(
IS_BLANK,
(FunctionImp1)
Expand Down
36 changes: 34 additions & 2 deletions docs/user/ppl/functions/condition.md
Original file line number Diff line number Diff line change
Expand Up @@ -642,8 +642,40 @@ fetched rows / total rows = 4/4
| False | | True | null |
+---------------+---------+-------------------+----------+
```

## EARLIEST

## ISNOTEMPTY

### Description

Usage: `isnotempty(field)` returns true if the field is not null and is not an empty string.

**Argument type:** All supported data types.
**Return type:** `BOOLEAN`

### Example

```ppl
source=accounts
| eval temp = ifnull(employer, ' ')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I didn't realize that isempty counted blank strings, I thought it only matched empty (zero-length) strings.

Weird imo, not this PR's fault.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually thought isempty only matched null and zero-length strings, not blank/whitespace. Isn't that what isblank is for? Or am I misunderstanding something?

| eval `isnotempty(employer)` = isnotempty(employer), `isnotempty(temp)` = isnotempty(temp)
| fields `isnotempty(temp)`, temp, `isnotempty(employer)`, employer
```

Expected output:

```text
fetched rows / total rows = 4/4
+------------------+---------+----------------------+----------+
| isnotempty(temp) | temp | isnotempty(employer) | employer |
|------------------+---------+----------------------+----------|
| True | Pyrami | True | Pyrami |
| True | Netagy | True | Netagy |
| True | Quility | True | Quility |
| True | | False | null |
+------------------+---------+----------------------+----------+
```

## EARLIEST

### Description

Expand Down
1 change: 1 addition & 0 deletions docs/user/ppl/functions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ PPL supports a wide range of built-in functions for data processing and analysis
- [ISPRESENT](condition.md/#ispresent)
- [ISBLANK](condition.md/#isblank)
- [ISEMPTY](condition.md/#isempty)
- [ISNOTEMPTY](condition.md/#isnotempty)
- [EARLIEST](condition.md/#earliest)
- [LATEST](condition.md/#latest)
- [REGEXP_MATCH](condition.md/#regexp_match)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,28 @@ public void testIsEmpty() throws IOException {
verifyDataRows(actual, rows(null, 10), rows("", 57));
}

@Test
public void testIsNotEmpty() throws IOException {
JSONObject actual =
executeQuery(
String.format(
"source=%s | where isnotempty(name) | fields name, age",
TEST_INDEX_STATE_COUNTRY_WITH_NULL));

verifySchema(actual, schema("name", "string"), schema("age", "int"));

// isnotempty = NOT isempty. isempty returns (null,10) and ("",57).
// So isnotempty returns everything else: Jake, Hello, John, Jane, Kevin, whitespace.
verifyDataRows(
actual,
rows("Jake", 70),
rows("Hello", 30),
rows("John", 25),
rows("Jane", 20),
rows("Kevin", null),
rows(" ", 27));
}

@Test
public void testIsBlank() throws IOException {
JSONObject actual =
Expand Down
1 change: 1 addition & 0 deletions language-grammar/src/main/antlr4/OpenSearchPPLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ BETWEEN: 'BETWEEN';
CIDRMATCH: 'CIDRMATCH';
ISPRESENT: 'ISPRESENT';
ISEMPTY: 'ISEMPTY';
ISNOTEMPTY: 'ISNOTEMPTY';
ISBLANK: 'ISBLANK';

// FLOWCONTROL FUNCTIONS
Expand Down
2 changes: 2 additions & 0 deletions language-grammar/src/main/antlr4/OpenSearchPPLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ conditionFunctionBase
| EARLIEST
| LATEST
| ISEMPTY
| ISNOTEMPTY
| ISBLANK
;

Expand All @@ -877,6 +878,7 @@ textFunctionName
| REPLACE
| REVERSE
| ISEMPTY
| ISNOTEMPTY
| ISBLANK
;

Expand Down
1 change: 1 addition & 0 deletions ppl/src/main/antlr/OpenSearchPPLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ CIDRMATCH: 'CIDRMATCH';
BETWEEN: 'BETWEEN';
ISPRESENT: 'ISPRESENT';
ISEMPTY: 'ISEMPTY';
ISNOTEMPTY: 'ISNOTEMPTY';
ISBLANK: 'ISBLANK';

// COLLECTION FUNCTIONS
Expand Down
1 change: 1 addition & 0 deletions ppl/src/main/antlr/OpenSearchPPLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,7 @@ conditionFunctionName
| JSON_VALID
| ISPRESENT
| ISEMPTY
| ISNOTEMPTY
| ISBLANK
| EARLIEST
| LATEST
Expand Down