This is an automated email from the ASF dual-hosted git repository.
jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 49126f2835 Polymorphic scalar function implementation for BETWEEN
(#14113)
49126f2835 is described below
commit 49126f28356a4fe61c7a23d330555109b4759ba0
Author: Yash Mayya <[email protected]>
AuthorDate: Wed Oct 2 07:00:11 2024 +0530
Polymorphic scalar function implementation for BETWEEN (#14113)
---
.../function/scalar/ComparisonFunctions.java | 32 ------
.../scalar/comparison/BetweenScalarFunction.java | 120 +++++++++++++++++++++
.../pinot/sql/parsers/CalciteSqlCompilerTest.java | 12 +++
3 files changed, 132 insertions(+), 32 deletions(-)
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/ComparisonFunctions.java
b/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/ComparisonFunctions.java
deleted file mode 100644
index 00a829e09c..0000000000
---
a/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/ComparisonFunctions.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.pinot.common.function.scalar;
-
-import org.apache.pinot.spi.annotations.ScalarFunction;
-
-public class ComparisonFunctions {
-
- private ComparisonFunctions() {
- }
-
- @ScalarFunction
- public static boolean between(double val, double a, double b) {
- return val >= a && val <= b;
- }
-}
diff --git
a/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/comparison/BetweenScalarFunction.java
b/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/comparison/BetweenScalarFunction.java
new file mode 100644
index 0000000000..9d68f816b9
--- /dev/null
+++
b/pinot-common/src/main/java/org/apache/pinot/common/function/scalar/comparison/BetweenScalarFunction.java
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.common.function.scalar.comparison;
+
+import java.math.BigDecimal;
+import java.util.EnumMap;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.apache.pinot.common.function.FunctionInfo;
+import org.apache.pinot.common.function.PinotScalarFunction;
+import org.apache.pinot.common.utils.DataSchema.ColumnDataType;
+import org.apache.pinot.spi.annotations.ScalarFunction;
+
+
+/**
+ * Polymorphic 'between' scalar function implementation.
+ */
+@ScalarFunction
+public class BetweenScalarFunction implements PinotScalarFunction {
+
+ private static final Map<ColumnDataType, FunctionInfo>
TYPE_FUNCTION_INFO_MAP = new EnumMap<>(ColumnDataType.class);
+
+ static {
+ try {
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.INT,
+ new FunctionInfo(BetweenScalarFunction.class.getMethod("intBetween",
int.class, int.class, int.class),
+ BetweenScalarFunction.class, false));
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.LONG,
+ new
FunctionInfo(BetweenScalarFunction.class.getMethod("longBetween", long.class,
long.class, long.class),
+ BetweenScalarFunction.class, false));
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.FLOAT,
+ new
FunctionInfo(BetweenScalarFunction.class.getMethod("floatBetween", float.class,
float.class, float.class),
+ BetweenScalarFunction.class, false));
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.DOUBLE, new FunctionInfo(
+ BetweenScalarFunction.class.getMethod("doubleBetween", double.class,
double.class, double.class),
+ BetweenScalarFunction.class, false));
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.BIG_DECIMAL, new FunctionInfo(
+ BetweenScalarFunction.class.getMethod("bigDecimalBetween",
BigDecimal.class, BigDecimal.class,
+ BigDecimal.class), BetweenScalarFunction.class, false));
+ TYPE_FUNCTION_INFO_MAP.put(ColumnDataType.STRING, new FunctionInfo(
+ BetweenScalarFunction.class.getMethod("stringBetween", String.class,
String.class, String.class),
+ BetweenScalarFunction.class, false));
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "between";
+ }
+
+ @Nullable
+ @Override
+ public FunctionInfo getFunctionInfo(ColumnDataType[] argumentTypes) {
+ if (argumentTypes.length != 3) {
+ return null;
+ }
+
+ if (argumentTypes[0].getStoredType() != argumentTypes[1].getStoredType()
+ || argumentTypes[0].getStoredType() !=
argumentTypes[2].getStoredType()) {
+ // In case of heterogeneous argument types, fall back to double based
comparison and allow FunctionInvoker to
+ // convert argument types for v1 engine support.
+ return TYPE_FUNCTION_INFO_MAP.get(ColumnDataType.DOUBLE);
+ }
+
+ return TYPE_FUNCTION_INFO_MAP.get(argumentTypes[0].getStoredType());
+ }
+
+ @Nullable
+ @Override
+ public FunctionInfo getFunctionInfo(int numArguments) {
+ if (numArguments != 3) {
+ return null;
+ }
+
+ // Fall back to double based comparison by default for backward
compatibility
+ return TYPE_FUNCTION_INFO_MAP.get(ColumnDataType.DOUBLE);
+ }
+
+ public static boolean intBetween(int val, int lower, int upper) {
+ return val >= lower && val <= upper;
+ }
+
+ public static boolean longBetween(long val, long lower, long upper) {
+ return val >= lower && val <= upper;
+ }
+
+ public static boolean floatBetween(float val, float lower, float upper) {
+ return val >= lower && val <= upper;
+ }
+
+ public static boolean doubleBetween(double val, double lower, double upper) {
+ return val >= lower && val <= upper;
+ }
+
+ public static boolean bigDecimalBetween(BigDecimal val, BigDecimal lower,
BigDecimal upper) {
+ return val.compareTo(lower) >= 0 && val.compareTo(upper) <= 0;
+ }
+
+ public static boolean stringBetween(String val, String lower, String upper) {
+ return val.compareTo(lower) >= 0 && val.compareTo(upper) <= 0;
+ }
+}
diff --git
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
index 34e2a6b5f5..67940a64c0 100644
---
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
@@ -2315,6 +2315,18 @@ public class CalciteSqlCompilerTest {
pinotQuery = compileToPinotQuery(query);
result = pinotQuery.getSelectList().get(0).getLiteral().getBoolValue();
Assert.assertTrue(result);
+
+ query = "select * from mytable where 'm' between 'a' and 'z'";
+ pinotQuery = compileToPinotQuery(query);
+ Assert.assertTrue(pinotQuery.getFilterExpression().isSetLiteral());
+ result = pinotQuery.getFilterExpression().getLiteral().getBoolValue();
+ Assert.assertTrue(result);
+
+ query = "select * from mytable where 5 between 0 and 10";
+ pinotQuery = compileToPinotQuery(query);
+ Assert.assertTrue(pinotQuery.getFilterExpression().isSetLiteral());
+ result = pinotQuery.getFilterExpression().getLiteral().getBoolValue();
+ Assert.assertTrue(result);
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]