Skip to content

Commit

Permalink
add string function RIGHT (opendistro-for-elasticsearch#938)
Browse files Browse the repository at this point in the history
* add right function

* update doc

* address PR comments

* fix build failure

Co-authored-by: Rupal Mahajan <>
  • Loading branch information
rupal-bq authored and penghuo committed Dec 16, 2020
1 parent 7b1a784 commit dc53a74
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,10 @@ public FunctionExpression strcmp(Expression... expressions) {
return function(BuiltinFunctionName.STRCMP, expressions);
}

public FunctionExpression right(Expression... expressions) {
return function(BuiltinFunctionName.RIGHT, expressions);
}

public FunctionExpression and(Expression... expressions) {
return function(BuiltinFunctionName.AND, expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ public enum BuiltinFunctionName {
CONCAT_WS(FunctionName.of("concat_ws")),
LENGTH(FunctionName.of("length")),
STRCMP(FunctionName.of("strcmp")),
RIGHT(FunctionName.of("right")),

/**
* NULL Test.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public void register(BuiltinFunctionRepository repository) {
repository.register(concat_ws());
repository.register(length());
repository.register(strcmp());
repository.register(right());
}

/**
Expand Down Expand Up @@ -194,6 +195,16 @@ private FunctionResolver strcmp() {
INTEGER, STRING, STRING));
}

/**
* Returns the rightmost len characters from the string str, or NULL if any argument is NULL.
* Supports following signatures:
* (STRING, INTEGER) -> STRING
*/
private FunctionResolver right() {
return define(BuiltinFunctionName.RIGHT.getName(),
impl(nullMissingHandling(TextFunction::exprRight), STRING, STRING, INTEGER));
}

private static ExprValue exprSubstrStart(ExprValue exprValue, ExprValue start) {
int startIdx = start.integerValue();
if (startIdx == 0) {
Expand Down Expand Up @@ -225,5 +236,10 @@ private static ExprValue exprSubStr(String str, int start, int len) {
}
return new ExprStringValue(str.substring(start, start + len));
}

private static ExprValue exprRight(ExprValue str, ExprValue len) {
return new ExprStringValue(str.stringValue().substring(
str.stringValue().length() - len.integerValue()));
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import com.amazon.opendistroforelasticsearch.sql.data.model.ExprIntegerValue;
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprStringValue;
import com.amazon.opendistroforelasticsearch.sql.data.model.ExprValue;
import com.amazon.opendistroforelasticsearch.sql.expression.DSL;
Expand Down Expand Up @@ -296,6 +297,23 @@ void strcmp() {
assertEquals(missingValue(), eval(dsl.strcmp(missingRef, nullRef)));
}

@Test
void right() {
FunctionExpression expression = dsl.right(
DSL.literal(new ExprStringValue("foobarbar")),
DSL.literal(new ExprIntegerValue(4)));
assertEquals(STRING, expression.type());
assertEquals("rbar", eval(expression).stringValue());

when(nullRef.type()).thenReturn(STRING);
when(missingRef.type()).thenReturn(INTEGER);
assertEquals(missingValue(), eval(dsl.right(nullRef, missingRef)));
assertEquals(nullValue(), eval(dsl.right(nullRef, DSL.literal(new ExprIntegerValue(1)))));

when(nullRef.type()).thenReturn(INTEGER);
assertEquals(nullValue(), eval(dsl.right(DSL.literal(new ExprStringValue("value")), nullRef)));
}

void testConcatString(List<String> strings) {
String expected = null;
if (strings.stream().noneMatch(Objects::isNull)) {
Expand Down
23 changes: 23 additions & 0 deletions docs/experiment/ppl/functions/string.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,29 @@ Example::
+---------------------+---------------------+


RIGHT
-----

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

Usage: right(str, len) returns the rightmost len characters from the string str, or NULL if any argument is NULL.

Argument type: STRING, INTEGER

Return type: STRING

Example::

od> source=people | eval `RIGHT('helloworld', 5)` = RIGHT('helloworld', 5), `RIGHT('HELLOWORLD', 0)` = RIGHT('HELLOWORLD', 0) | fields `RIGHT('helloworld', 5)`, `RIGHT('HELLOWORLD', 0)`
fetched rows / total rows = 1/1
+--------------------------+--------------------------+
| RIGHT('helloworld', 5) | RIGHT('HELLOWORLD', 0) |
|--------------------------+--------------------------|
| world | |
+--------------------------+--------------------------+


RTRIM
-----

Expand Down
16 changes: 14 additions & 2 deletions docs/user/dql/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1760,9 +1760,21 @@ RIGHT
Description
>>>>>>>>>>>

Specifications:
Usage: right(str, len) returns the rightmost len characters from the string str, or NULL if any argument is NULL.

Argument type: STRING, INTEGER

Return type: STRING

1. RIGHT(STRING T, INTEGER) -> T
Example::

od> SELECT RIGHT('helloworld', 5), RIGHT('HELLOWORLD', 0)
fetched rows / total rows = 1/1
+--------------------------+--------------------------+
| RIGHT('helloworld', 5) | RIGHT('HELLOWORLD', 0) |
|--------------------------+--------------------------|
| world | |
+--------------------------+--------------------------+


RTRIM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ public void testTrim() throws IOException {
verifyQuery("trim", "", "", "hello", "world", "helloworld");
}

@Test
public void testRight() throws IOException {
verifyQuery("right", "", ", 3", "llo", "rld", "rld");
}

@Test
public void testRtrim() throws IOException {
verifyQuery("rtrim", "", "", "hello", "world", "helloworld");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ public void testStrcmp() throws IOException {
verifyQuery("strcmp('hello', 'hello')", "integer", 0);
}

@Test
public void testRight() throws IOException {
verifyQuery("right('variable', 4)", "keyword", "able");
}

protected JSONObject executeQuery(String query) throws IOException {
Request request = new Request("POST", QUERY_API_ENDPOINT);
request.setJsonEntity(String.format(Locale.ROOT, "{\n" + " \"query\": \"%s\"\n" + "}", query));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
RIGHT('Hello World', 5) as column
1 change: 1 addition & 0 deletions ppl/src/main/antlr/OpenDistroPPLLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ CONCAT: 'CONCAT';
CONCAT_WS: 'CONCAT_WS';
LENGTH: 'LENGTH';
STRCMP: 'STRCMP';
RIGHT: 'RIGHT';

// BOOL FUNCTIONS
LIKE: 'LIKE';
Expand Down
1 change: 1 addition & 0 deletions ppl/src/main/antlr/OpenDistroPPLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ conditionFunctionBase

textFunctionBase
: SUBSTR | SUBSTRING | TRIM | LTRIM | RTRIM | LOWER | UPPER | CONCAT | CONCAT_WS | LENGTH | STRCMP
| RIGHT
;

/** operators */
Expand Down
2 changes: 1 addition & 1 deletion sql/src/main/antlr/OpenDistroSQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ dateTimeFunctionName

textFunctionName
: SUBSTR | SUBSTRING | TRIM | LTRIM | RTRIM | LOWER | UPPER
| CONCAT | CONCAT_WS | SUBSTR | LENGTH | STRCMP
| CONCAT | CONCAT_WS | SUBSTR | LENGTH | STRCMP | RIGHT
;

functionArgs
Expand Down

0 comments on commit dc53a74

Please sign in to comment.