Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Implemented "greatest" and "least" functions in old engine
Browse files Browse the repository at this point in the history
  • Loading branch information
cip999 committed Aug 21, 2021
1 parent 7eeb805 commit 953ad26
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package com.amazon.opendistroforelasticsearch.sql.legacy;

import static com.amazon.opendistroforelasticsearch.sql.legacy.TestsConstants.TEST_INDEX_ACCOUNT;
import static com.amazon.opendistroforelasticsearch.sql.legacy.TestsConstants.TEST_INDEX_DATE;
import static com.amazon.opendistroforelasticsearch.sql.legacy.TestsConstants.TEST_INDEX_DATE_TIME;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.hitAny;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.kvDouble;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.kvInt;
Expand Down Expand Up @@ -68,6 +70,7 @@ protected void init() throws Exception {
loadIndex(Index.BANK);
loadIndex(Index.ONLINE);
loadIndex(Index.DATE);
loadIndex(Index.DATETIME);
}

@Test
Expand Down Expand Up @@ -877,6 +880,18 @@ public void literalMultiField() throws Exception {
assertThat(hits[0].getFields(), allOf(hasValue(contains(1)), hasValue(contains(2))));
}

@Test
public void greatestWithAliasAndStrings() throws Exception {
JSONObject response =
executeJdbcRequest("SELECT greatest(firstname, lastname) AS max " +
"FROM " + TEST_INDEX_ACCOUNT + " LIMIT 3");

verifyDataRows(response,
rows("duke"),
rows("hattie"),
rows("nanette"));
}

private SearchHits query(String query) throws IOException {
final String rsp = executeQueryWithStringOutput(query);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,19 @@ public enum ScalarFunction implements TypeExpression {
EXP(func(T(NUMBER)).to(T)),
EXPM1(func(T(NUMBER)).to(T)),
FLOOR(func(T(NUMBER)).to(T)),
GREATEST(
func(T(NUMBER), NUMBER).to(T),
func(T(STRING), STRING).to(T),
func(ESDataType.DATE, ESDataType.DATE).to(ESDataType.DATE)
),
IF(func(BOOLEAN, ES_TYPE, ES_TYPE).to(ES_TYPE)),
IFNULL(func(ES_TYPE, ES_TYPE).to(ES_TYPE)),
ISNULL(func(ES_TYPE).to(INTEGER)),
LEAST(
func(T(NUMBER), NUMBER).to(T),
func(T(STRING), STRING).to(T),
func(ESDataType.DATE, ESDataType.DATE).to(ESDataType.DATE)
),
LEFT(func(T(STRING), INTEGER).to(T)),
LENGTH(func(STRING).to(INTEGER)),
LN(func(T(NUMBER)).to(DOUBLE)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public class SQLFunctions {
);

private static final Set<String> binaryOperators = Sets.newHashSet(
"add", "multiply", "divide", "subtract", "modulus"
"add", "multiply", "divide", "subtract", "modulus", "greatest", "least"
);

private static final Set<String> dateFunctions = Sets.newHashSet(
Expand Down Expand Up @@ -332,6 +332,13 @@ public Tuple<String, String> function(String methodName, List<KVValue> paramers,
functionStr = modulus((SQLExpr) paramers.get(0).value, (SQLExpr) paramers.get(1).value);
break;

case "greatest":
functionStr = greatest((SQLExpr) paramers.get(0).value, (SQLExpr) paramers.get(1).value);
break;
case "least":
functionStr = least((SQLExpr) paramers.get(0).value, (SQLExpr) paramers.get(1).value);
break;

case "field":
functionStr = field(Util.expr2Object((SQLExpr) paramers.get(0).value).toString());
break;
Expand Down Expand Up @@ -596,6 +603,56 @@ private Tuple<String, String> binaryOpertator(String methodName, String operator
+ def(name, extractName(a) + " " + operator + " " + extractName(b)));
}

private Tuple<String, String> greatest(SQLExpr a, SQLExpr b) {
String name = nextId("greatest");

String name_a = extractName(a);
String name_b = extractName(b);

String value_a = getPropertyOrStringValue(a);
String value_b = getPropertyOrStringValue(b);

String nameString_a = nextId("string_a");
String nameString_b = nextId("string_b");

return new Tuple<>(name,
scriptDeclare(a) + scriptDeclare(b)
+ "def " + name + ";"
+ String.format("if (%s instanceof Number) ", name_a)
+ String.format("{%s = (%s >= %s ? %s : %s);} ", name, name_a, name_b, name_a, name_b)
+ "else {"
+ def(nameString_a, convertToString(value_a)) + ";"
+ def(nameString_b, convertToString(value_b)) + ";"
+ String.format("%s = (%s.compareTo(%s) >= 0 ? %s : %s);}",
name, nameString_a, nameString_b, value_a, value_b)
+ name + " = " + name);
}

private Tuple<String, String> least(SQLExpr a, SQLExpr b) {
String name = nextId("least");

String name_a = extractName(a);
String name_b = extractName(b);

String value_a = getPropertyOrStringValue(a);
String value_b = getPropertyOrStringValue(b);

String nameString_a = nextId("string_a");
String nameString_b = nextId("string_b");

return new Tuple<>(name,
scriptDeclare(a) + scriptDeclare(b)
+ "def " + name + ";"
+ String.format("if (%s instanceof Number) ", name_a)
+ String.format("{%s = (%s <= %s ? %s : %s);} ", name, name_a, name_b, name_a, name_b)
+ "else {"
+ def(nameString_a, convertToString(value_a)) + ";"
+ def(nameString_b, convertToString(value_b)) + ";"
+ String.format("%s = (%s.compareTo(%s) <= 0 ? %s : %s);}",
name, nameString_a, nameString_b, value_a, value_b)
+ name + " = " + name);
}

private static boolean isProperty(SQLExpr expr) {
return (expr instanceof SQLIdentifierExpr || expr instanceof SQLPropertyExpr
|| expr instanceof SQLVariantRefExpr);
Expand Down Expand Up @@ -628,7 +685,6 @@ private static String getPropertyOrStringValue(SQLExpr expr) {
}

private static String scriptDeclare(SQLExpr a) {

if (isProperty(a) || a instanceof SQLNumericLiteralExpr) {
return "";
} else {
Expand Down Expand Up @@ -668,6 +724,11 @@ private static String convertType(SQLExpr script) {

}

private static String convertToString(String name) {
return String.format("(%s instanceof String ? (String) %s : %s.toString())",
name, name, name);
}

private String getScriptText(MethodField field) {
String content = ((SQLTextLiteralExpr) field.getParams().get(1).value).getText();
return content;
Expand Down

0 comments on commit 953ad26

Please sign in to comment.