Skip to content

Commit 3e6fe44

Browse files
committed
Merge origin/main into coalesce-udf
Signed-off-by: Yuanchun Shen <yuanchu@amazon.com>
2 parents 0f39164 + 94fb171 commit 3e6fe44

48 files changed

Lines changed: 19390 additions & 6 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ public enum BuiltinFunctionName {
228228
ISNULL(FunctionName.of("isnull")),
229229
COALESCE(FunctionName.of("coalesce")),
230230

231+
IS_PRESENT(FunctionName.of("ispresent")),
232+
IS_EMPTY(FunctionName.of("isempty")),
233+
IS_BLANK(FunctionName.of("isblank")),
234+
231235
ROW_NUMBER(FunctionName.of("row_number")),
232236
RANK(FunctionName.of("rank")),
233237
DENSE_RANK(FunctionName.of("dense_rank")),

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ void populate() {
199199
registerOperator(SIN, SqlStdOperatorTable.SIN);
200200
registerOperator(CBRT, SqlStdOperatorTable.CBRT);
201201
registerOperator(IS_NOT_NULL, SqlStdOperatorTable.IS_NOT_NULL);
202+
registerOperator(IS_PRESENT, SqlStdOperatorTable.IS_NOT_NULL);
202203
registerOperator(IS_NULL, SqlStdOperatorTable.IS_NULL);
203204
registerOperator(IF, SqlStdOperatorTable.CASE);
204205
registerOperator(IFNULL, SqlStdOperatorTable.COALESCE);
@@ -372,6 +373,28 @@ void populate() {
372373
builder.makeCall(SqlStdOperatorTable.EQUALS, arg1, arg2),
373374
builder.makeNullLiteral(arg1.getType()),
374375
arg1));
376+
register(
377+
IS_EMPTY,
378+
((FunctionImp1)
379+
(builder, arg) ->
380+
builder.makeCall(
381+
SqlStdOperatorTable.OR,
382+
builder.makeCall(SqlStdOperatorTable.IS_NULL, arg),
383+
builder.makeCall(SqlStdOperatorTable.IS_EMPTY, arg))));
384+
register(
385+
IS_BLANK,
386+
((FunctionImp1)
387+
(builder, arg) ->
388+
builder.makeCall(
389+
SqlStdOperatorTable.OR,
390+
builder.makeCall(SqlStdOperatorTable.IS_NULL, arg),
391+
builder.makeCall(
392+
SqlStdOperatorTable.IS_EMPTY,
393+
builder.makeCall(
394+
SqlStdOperatorTable.TRIM,
395+
builder.makeFlag(Flag.BOTH),
396+
builder.makeLiteral(" "),
397+
arg)))));
375398
}
376399
}
377400

docs/user/ppl/functions/condition.rst

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Argument type: all the supported data type.
4545

4646
Return type: BOOLEAN
4747

48+
Synonyms: `ISPRESENT`_
49+
4850
Example::
4951

5052
os> source=accounts | where not isnotnull(employer) | fields account_number, employer
@@ -264,3 +266,86 @@ Example::
264266
| Quility | Nanette | Bates | Quility |
265267
| Dale | Dale | Adams | null |
266268
+---------+-----------+----------+----------+
269+
270+
ISPRESENT
271+
---------
272+
273+
Description
274+
>>>>>>>>>>>
275+
276+
Version: 3.1.0
277+
278+
Usage: ispresent(field) return true if the field exists.
279+
280+
Argument type: all the supported data type.
281+
282+
Return type: BOOLEAN
283+
284+
Synonyms: `ISNOTNULL`_
285+
286+
Example::
287+
288+
PPL> source=accounts | where ispresent(employer) | fields employer, firstname
289+
fetched rows / total rows = 3/3
290+
+----------+-----------+
291+
| employer | firstname |
292+
|----------+-----------|
293+
| Pyrami | Amber |
294+
| Netagy | Hattie |
295+
| Quility | Nanette |
296+
+----------+-----------+
297+
298+
ISBLANK
299+
-------
300+
301+
Description
302+
>>>>>>>>>>>
303+
304+
Version: 3.1.0
305+
306+
Usage: isblank(field) returns true if the field is null, an empty string, or contains only white space.
307+
308+
Argument type: all the supported data type.
309+
310+
Return type: BOOLEAN
311+
312+
Example::
313+
314+
PPL> source=accounts | eval temp = ifnull(employer, ' ') | eval `isblank(employer)` = isblank(employer), `isblank(temp)` = isblank(temp) | fields `isblank(temp)`, temp, `isblank(employer)`, employer
315+
fetched rows / total rows = 4/4
316+
+---------------+---------+-------------------+----------+
317+
| isblank(temp) | temp | isblank(employer) | employer |
318+
|---------------+---------+-------------------+----------|
319+
| False | Pyrami | False | Pyrami |
320+
| False | Netagy | False | Netagy |
321+
| False | Quility | False | Quility |
322+
| True | | True | null |
323+
+---------------+---------+-------------------+----------+
324+
325+
326+
ISEMPTY
327+
-------
328+
329+
Description
330+
>>>>>>>>>>>
331+
332+
Version: 3.1.0
333+
334+
Usage: isempty(field) returns true if the field is null or is an empty string.
335+
336+
Argument type: all the supported data type.
337+
338+
Return type: BOOLEAN
339+
340+
Example::
341+
342+
PPL> source=accounts | eval temp = ifnull(employer, ' ') | eval `isempty(employer)` = isempty(employer), `isempty(temp)` = isempty(temp) | fields `isempty(temp)`, temp, `isempty(employer)`, employer
343+
fetched rows / total rows = 4/4
344+
+---------------+---------+-------------------+----------+
345+
| isempty(temp) | temp | isempty(employer) | employer |
346+
|---------------+---------+-------------------+----------|
347+
| False | Pyrami | False | Pyrami |
348+
| False | Netagy | False | Netagy |
349+
| False | Quility | False | Quility |
350+
| False | | True | null |
351+
+---------------+---------+-------------------+----------+

docs/user/ppl/functions/cryptographic.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ MD5
1414
Description
1515
>>>>>>>>>>>
1616

17+
Version: 3.1.0
1718

1819
Usage: ``md5(str)`` calculates the MD5 digest and returns the value as a 32 character hex string.
1920

@@ -37,6 +38,8 @@ SHA1
3738
Description
3839
>>>>>>>>>>>
3940

41+
Version: 3.1.0
42+
4043
Usage: ``sha1(str)`` returns the hex string result of SHA-1.
4144

4245
Argument type: STRING
@@ -59,6 +62,8 @@ SHA2
5962
Description
6063
>>>>>>>>>>>
6164

65+
Version: 3.1.0
66+
6267
Usage: ``sha2(str, numBits)`` returns the hex string result of SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, and SHA-512).
6368
The numBits indicates the desired bit length of the result, which must have a value of 224, 256, 384, or 512.
6469

integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLConditionBuiltinFunctionIT.java

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,25 @@
1313
import java.io.IOException;
1414
import org.json.JSONObject;
1515
import org.junit.jupiter.api.Test;
16+
import org.opensearch.client.Request;
1617

1718
public class CalcitePPLConditionBuiltinFunctionIT extends CalcitePPLIntegTestCase {
1819
@Override
1920
public void init() throws IOException {
2021
super.init();
2122
loadIndex(Index.STATE_COUNTRY);
2223
loadIndex(Index.STATE_COUNTRY_WITH_NULL);
24+
Request request1 =
25+
new Request("PUT", "/" + TEST_INDEX_STATE_COUNTRY_WITH_NULL + "/_doc/7?refresh=true");
26+
request1.setJsonEntity(
27+
"{\"name\":\" "
28+
+ " \",\"age\":27,\"state\":\"B.C\",\"country\":\"Canada\",\"year\":2023,\"month\":4}");
29+
client().performRequest(request1);
30+
Request request2 =
31+
new Request("PUT", "/" + TEST_INDEX_STATE_COUNTRY_WITH_NULL + "/_doc/8?refresh=true");
32+
request2.setJsonEntity(
33+
"{\"name\":\"\",\"age\":57,\"state\":\"B.C\",\"country\":\"Canada\",\"year\":2023,\"month\":4}");
34+
client().performRequest(request2);
2335
}
2436

2537
@Test
@@ -44,7 +56,15 @@ public void testIsNotNull() {
4456

4557
verifySchema(actual, schema("name", "string"));
4658

47-
verifyDataRows(actual, rows("John"), rows("Jane"), rows("Jake"), rows("Hello"), rows("Kevin"));
59+
verifyDataRows(
60+
actual,
61+
rows("John"),
62+
rows("Jane"),
63+
rows("Jake"),
64+
rows("Hello"),
65+
rows("Kevin"),
66+
rows(" "),
67+
rows(""));
4868
}
4969

5070
@Test
@@ -64,7 +84,9 @@ public void testNullIf() {
6484
rows(null, 10),
6585
rows("Jake", 70),
6686
rows("Kevin", null),
67-
rows("Hello", 30));
87+
rows("Hello", 30),
88+
rows(" ", 27),
89+
rows("", 57));
6890
}
6991

7092
@Test
@@ -85,7 +107,9 @@ public void testNullIfWithExpression() {
85107
rows(null, null),
86108
rows("Jake", "HJake"),
87109
rows("Kevin", "HKevin"),
88-
rows("Hello", null));
110+
rows("Hello", null),
111+
rows(" ", "H "),
112+
rows("", "H"));
89113
}
90114

91115
@Test
@@ -105,7 +129,9 @@ public void testIfNull() {
105129
rows("Unknown", 10),
106130
rows("Jake", 70),
107131
rows("Kevin", null),
108-
rows("Hello", 30));
132+
rows("Hello", 30),
133+
rows(" ", 27),
134+
rows("", 57));
109135
}
110136

111137
@Test
@@ -146,7 +172,9 @@ public void testIf() {
146172
rows("young", 20),
147173
rows("young", 10),
148174
rows("old", 70),
149-
rows("young", 30));
175+
rows("young", 30),
176+
rows("young", 27),
177+
rows("old", 57));
150178
}
151179

152180
@Test
@@ -162,4 +190,51 @@ public void testIfWithLike() {
162190
verifyDataRows(
163191
actual, rows(0.0, "John"), rows(0.0, "Jane"), rows(0.0, "Jake"), rows(1.0, "Hello"));
164192
}
193+
194+
@Test
195+
public void testIsPresent() throws IOException {
196+
JSONObject actual =
197+
executeQuery(
198+
String.format(
199+
"source=%s | where ispresent(name) | fields name, age",
200+
TEST_INDEX_STATE_COUNTRY_WITH_NULL));
201+
202+
verifySchema(actual, schema("name", "string"), schema("age", "integer"));
203+
204+
verifyDataRows(
205+
actual,
206+
rows("Jake", 70),
207+
rows("Hello", 30),
208+
rows("John", 25),
209+
rows("Jane", 20),
210+
rows("Kevin", null),
211+
rows(" ", 27),
212+
rows("", 57));
213+
}
214+
215+
@Test
216+
public void testIsEmpty() throws IOException {
217+
JSONObject actual =
218+
executeQuery(
219+
String.format(
220+
"source=%s | where isempty(name) | fields name, age",
221+
TEST_INDEX_STATE_COUNTRY_WITH_NULL));
222+
223+
verifySchema(actual, schema("name", "string"), schema("age", "integer"));
224+
225+
verifyDataRows(actual, rows(null, 10), rows("", 57));
226+
}
227+
228+
@Test
229+
public void testIsBlank() throws IOException {
230+
JSONObject actual =
231+
executeQuery(
232+
String.format(
233+
"source=%s | where isblank(name) | fields name, age",
234+
TEST_INDEX_STATE_COUNTRY_WITH_NULL));
235+
236+
verifySchema(actual, schema("name", "string"), schema("age", "integer"));
237+
238+
verifyDataRows(actual, rows(null, 10), rows(" ", 27), rows("", 57));
239+
}
165240
}

0 commit comments

Comments
 (0)