Skip to content

Commit 0fc6d2d

Browse files
Add missing udfs in v3 (#3957) (#4011)
* add math udfs * fix decimal bug * make general udf adapter * add math IT * fix * add rst * fix error * change signum IT * add javadoc --------- (cherry picked from commit d6aac3c) Signed-off-by: Xinyu Hao <haoxinyu@amazon.com> Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent a6dfdd4 commit 0fc6d2d

File tree

7 files changed

+438
-9
lines changed

7 files changed

+438
-9
lines changed

core/src/main/java/org/opensearch/sql/calcite/utils/UserDefinedFunctionUtils.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,47 @@ public UDFOperandMetadata getOperandMetadata() {
228228
};
229229
}
230230

231+
/**
232+
* Adapt a static math function (e.g., Math.expm1, Math.rint) to a UserDefinedFunctionBuilder.
233+
* This method generates a Calcite-compatible UDF by boxing the operand, converting it to a
234+
* double, and then calling the corresponding method in {@link Math}.
235+
*
236+
* <p>It assumes the math method has the signature: {@code double method(double)}. This utility is
237+
* specifically designed for single-operand Math methods.
238+
*
239+
* @param methodName the name of the static method in {@link Math} to be invoked
240+
* @param returnTypeInference the return type inference of the UDF
241+
* @param nullPolicy the null policy of the UDF
242+
* @param operandMetadata type checker
243+
* @return an adapted ImplementorUDF with the math method, which is a UserDefinedFunctionBuilder
244+
*/
245+
public static ImplementorUDF adaptMathFunctionToUDF(
246+
String methodName,
247+
SqlReturnTypeInference returnTypeInference,
248+
NullPolicy nullPolicy,
249+
UDFOperandMetadata operandMetadata) {
250+
251+
NotNullImplementor implementor =
252+
(translator, call, translatedOperands) -> {
253+
Expression operand = translatedOperands.get(0);
254+
operand = Expressions.box(operand);
255+
operand = Expressions.call(operand, "doubleValue");
256+
return Expressions.call(Math.class, methodName, operand);
257+
};
258+
259+
return new ImplementorUDF(implementor, nullPolicy) {
260+
@Override
261+
public SqlReturnTypeInference getReturnTypeInference() {
262+
return returnTypeInference;
263+
}
264+
265+
@Override
266+
public UDFOperandMetadata getOperandMetadata() {
267+
return operandMetadata;
268+
}
269+
};
270+
}
271+
231272
public static List<Expression> prependFunctionProperties(
232273
List<Expression> operands, RexToLixTranslator translator) {
233274
List<Expression> operandsWithProperties = new ArrayList<>(operands);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.adaptExprMethodToUDF;
99
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.adaptExprMethodWithPropertiesToUDF;
10+
import static org.opensearch.sql.calcite.utils.UserDefinedFunctionUtils.adaptMathFunctionToUDF;
1011

1112
import com.google.common.base.Suppliers;
1213
import java.lang.reflect.InvocationTargetException;
@@ -107,6 +108,26 @@ public class PPLBuiltinOperators extends ReflectiveSqlOperatorTable {
107108
public static final SqlOperator SHA2 = CryptographicFunction.sha2().toUDF("SHA2");
108109
public static final SqlOperator CIDRMATCH = new CidrMatchFunction().toUDF("CIDRMATCH");
109110

111+
public static final SqlOperator COSH =
112+
adaptMathFunctionToUDF(
113+
"cosh", ReturnTypes.DOUBLE_FORCE_NULLABLE, NullPolicy.ANY, PPLOperandTypes.NUMERIC)
114+
.toUDF("COSH");
115+
116+
public static final SqlOperator SINH =
117+
adaptMathFunctionToUDF(
118+
"sinh", ReturnTypes.DOUBLE_FORCE_NULLABLE, NullPolicy.ANY, PPLOperandTypes.NUMERIC)
119+
.toUDF("SINH");
120+
121+
public static final SqlOperator RINT =
122+
adaptMathFunctionToUDF(
123+
"rint", ReturnTypes.DOUBLE_FORCE_NULLABLE, NullPolicy.ANY, PPLOperandTypes.NUMERIC)
124+
.toUDF("RINT");
125+
126+
public static final SqlOperator EXPM1 =
127+
adaptMathFunctionToUDF(
128+
"expm1", ReturnTypes.DOUBLE_FORCE_NULLABLE, NullPolicy.ANY, PPLOperandTypes.NUMERIC)
129+
.toUDF("EXPM1");
130+
110131
// IP comparing functions
111132
public static final SqlOperator NOT_EQUALS_IP =
112133
CompareIpFunction.notEquals().toUDF("NOT_EQUALS_IP");

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ACOS;
1919
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ADD;
2020
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ADDDATE;
21+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ADDFUNCTION;
2122
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ADDTIME;
2223
import static org.opensearch.sql.expression.function.BuiltinFunctionName.AND;
2324
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ARRAY;
@@ -37,6 +38,7 @@
3738
import static org.opensearch.sql.expression.function.BuiltinFunctionName.CONV;
3839
import static org.opensearch.sql.expression.function.BuiltinFunctionName.CONVERT_TZ;
3940
import static org.opensearch.sql.expression.function.BuiltinFunctionName.COS;
41+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.COSH;
4042
import static org.opensearch.sql.expression.function.BuiltinFunctionName.COT;
4143
import static org.opensearch.sql.expression.function.BuiltinFunctionName.COUNT;
4244
import static org.opensearch.sql.expression.function.BuiltinFunctionName.CRC32;
@@ -61,11 +63,13 @@
6163
import static org.opensearch.sql.expression.function.BuiltinFunctionName.DAY_OF_YEAR;
6264
import static org.opensearch.sql.expression.function.BuiltinFunctionName.DEGREES;
6365
import static org.opensearch.sql.expression.function.BuiltinFunctionName.DIVIDE;
66+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.DIVIDEFUNCTION;
6467
import static org.opensearch.sql.expression.function.BuiltinFunctionName.E;
6568
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EARLIEST;
6669
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EQUAL;
6770
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EXISTS;
6871
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EXP;
72+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EXPM1;
6973
import static org.opensearch.sql.expression.function.BuiltinFunctionName.EXTRACT;
7074
import static org.opensearch.sql.expression.function.BuiltinFunctionName.FILTER;
7175
import static org.opensearch.sql.expression.function.BuiltinFunctionName.FLOOR;
@@ -137,6 +141,7 @@
137141
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MONTHNAME;
138142
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MONTH_OF_YEAR;
139143
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MULTIPLY;
144+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MULTIPLYFUNCTION;
140145
import static org.opensearch.sql.expression.function.BuiltinFunctionName.MULTI_MATCH;
141146
import static org.opensearch.sql.expression.function.BuiltinFunctionName.NOT;
142147
import static org.opensearch.sql.expression.function.BuiltinFunctionName.NOTEQUAL;
@@ -159,6 +164,7 @@
159164
import static org.opensearch.sql.expression.function.BuiltinFunctionName.REPLACE;
160165
import static org.opensearch.sql.expression.function.BuiltinFunctionName.REVERSE;
161166
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RIGHT;
167+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RINT;
162168
import static org.opensearch.sql.expression.function.BuiltinFunctionName.ROUND;
163169
import static org.opensearch.sql.expression.function.BuiltinFunctionName.RTRIM;
164170
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SECOND;
@@ -167,8 +173,10 @@
167173
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SHA1;
168174
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SHA2;
169175
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIGN;
176+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIGNUM;
170177
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIMPLE_QUERY_STRING;
171178
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SIN;
179+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SINH;
172180
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SPAN;
173181
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SQRT;
174182
import static org.opensearch.sql.expression.function.BuiltinFunctionName.STDDEV_POP;
@@ -180,6 +188,7 @@
180188
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SUBSTRING;
181189
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SUBTIME;
182190
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SUBTRACT;
191+
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SUBTRACTFUNCTION;
183192
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SUM;
184193
import static org.opensearch.sql.expression.function.BuiltinFunctionName.SYSDATE;
185194
import static org.opensearch.sql.expression.function.BuiltinFunctionName.TAKE;
@@ -758,8 +767,11 @@ void populate() {
758767
registerOperator(OR, SqlStdOperatorTable.OR);
759768
registerOperator(NOT, SqlStdOperatorTable.NOT);
760769
registerOperator(ADD, SqlStdOperatorTable.PLUS);
770+
registerOperator(ADDFUNCTION, SqlStdOperatorTable.PLUS);
761771
registerOperator(SUBTRACT, SqlStdOperatorTable.MINUS);
772+
registerOperator(SUBTRACTFUNCTION, SqlStdOperatorTable.MINUS);
762773
registerOperator(MULTIPLY, SqlStdOperatorTable.MULTIPLY);
774+
registerOperator(MULTIPLYFUNCTION, SqlStdOperatorTable.MULTIPLY);
763775
registerOperator(TRUNCATE, SqlStdOperatorTable.TRUNCATE);
764776
registerOperator(ASCII, SqlStdOperatorTable.ASCII);
765777
registerOperator(LENGTH, SqlStdOperatorTable.CHAR_LENGTH);
@@ -789,6 +801,7 @@ void populate() {
789801
registerOperator(RAND, SqlStdOperatorTable.RAND);
790802
registerOperator(ROUND, SqlStdOperatorTable.ROUND);
791803
registerOperator(SIGN, SqlStdOperatorTable.SIGN);
804+
registerOperator(SIGNUM, SqlStdOperatorTable.SIGN);
792805
registerOperator(SIN, SqlStdOperatorTable.SIN);
793806
registerOperator(CBRT, SqlStdOperatorTable.CBRT);
794807
registerOperator(IS_NOT_NULL, SqlStdOperatorTable.IS_NOT_NULL);
@@ -814,6 +827,10 @@ void populate() {
814827
registerOperator(INTERNAL_REGEXP_REPLACE_3, SqlLibraryOperators.REGEXP_REPLACE_3);
815828

816829
// Register PPL UDF operator
830+
registerOperator(COSH, PPLBuiltinOperators.COSH);
831+
registerOperator(SINH, PPLBuiltinOperators.SINH);
832+
registerOperator(EXPM1, PPLBuiltinOperators.EXPM1);
833+
registerOperator(RINT, PPLBuiltinOperators.RINT);
817834
registerOperator(SPAN, PPLBuiltinOperators.SPAN);
818835
registerOperator(E, PPLBuiltinOperators.E);
819836
registerOperator(CONV, PPLBuiltinOperators.CONV);
@@ -822,6 +839,7 @@ void populate() {
822839
registerOperator(MODULUSFUNCTION, PPLBuiltinOperators.MOD);
823840
registerOperator(CRC32, PPLBuiltinOperators.CRC32);
824841
registerOperator(DIVIDE, PPLBuiltinOperators.DIVIDE);
842+
registerOperator(DIVIDEFUNCTION, PPLBuiltinOperators.DIVIDE);
825843
registerOperator(SHA2, PPLBuiltinOperators.SHA2);
826844
registerOperator(CIDRMATCH, PPLBuiltinOperators.CIDRMATCH);
827845
registerOperator(INTERNAL_GROK, PPLBuiltinOperators.GROK);

0 commit comments

Comments
 (0)