This is an automated email from the ASF dual-hosted git repository.

xiangfu 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 1ce2bf7aaf Add Boolean assertion transform functions. (#11547)
1ce2bf7aaf is described below

commit 1ce2bf7aaf32d8b725c27182b8c101ae9e0448c6
Author: Shen Yu <[email protected]>
AuthorDate: Sat Sep 9 19:39:33 2023 -0700

    Add Boolean assertion transform functions. (#11547)
    
    * Add Boolean assertion transform functions.
    
    * Use an abstract base class.
    
    * Add Apache license.
    
    * Fix typos.
    
    * Rename class and improve performance.
    
    * Fix method visibility.
    
    * Refinements.
    
    * Address comments.
---
 .../common/function/TransformFunctionType.java     |  4 ++
 .../function/FunctionDefinitionRegistryTest.java   |  2 +-
 .../BaseBooleanAssertionTransformFunction.java     | 83 ++++++++++++++++++++++
 .../function/IsFalseTransformFunction.java         | 48 +++++++++++++
 .../function/IsNotFalseTransformFunction.java      | 48 +++++++++++++
 .../function/IsNotTrueTransformFunction.java       | 48 +++++++++++++
 .../function/IsTrueTransformFunction.java          | 48 +++++++++++++
 .../function/TransformFunctionFactory.java         |  4 ++
 .../queries/NullHandlingEnabledQueriesTest.java    | 34 +++++++++
 9 files changed, 318 insertions(+), 1 deletion(-)

diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
index 89ed66daad..ab8e53a4e2 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/function/TransformFunctionType.java
@@ -78,6 +78,10 @@ public enum TransformFunctionType {
   IN("in"),
   NOT_IN("not_in"),
 
+  IS_TRUE("is_true"),
+  IS_NOT_TRUE("is_not_true"),
+  IS_FALSE("is_false"),
+  IS_NOT_FALSE("is_not_false"),
   IS_NULL("is_null"),
   IS_NOT_NULL("is_not_null"),
   COALESCE("coalesce"),
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/common/function/FunctionDefinitionRegistryTest.java
 
b/pinot-common/src/test/java/org/apache/pinot/common/function/FunctionDefinitionRegistryTest.java
index d5370fe79c..8ce8123fc9 100644
--- 
a/pinot-common/src/test/java/org/apache/pinot/common/function/FunctionDefinitionRegistryTest.java
+++ 
b/pinot-common/src/test/java/org/apache/pinot/common/function/FunctionDefinitionRegistryTest.java
@@ -44,7 +44,7 @@ public class FunctionDefinitionRegistryTest {
       // functions we are not supporting post transform anyway
       "valuein", "mapvalue", "inidset", "lookup", "groovy", "scalar", 
"geotoh3", "not_in", "timeconvert",
       // functions not needed for register b/c they are in std sql table or 
they will not be composed directly.
-      "in", "and", "or", "range", "extract"
+      "in", "and", "or", "range", "extract", "is_true", "is_not_true", 
"is_false", "is_not_false"
   );
 
   @Test
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BaseBooleanAssertionTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BaseBooleanAssertionTransformFunction.java
new file mode 100644
index 0000000000..a75b0a5fd8
--- /dev/null
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BaseBooleanAssertionTransformFunction.java
@@ -0,0 +1,83 @@
+/**
+ * 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.core.operator.transform.function;
+
+import com.google.common.base.Preconditions;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.apache.pinot.core.operator.ColumnContext;
+import org.apache.pinot.core.operator.blocks.ValueBlock;
+import org.apache.pinot.core.operator.transform.TransformResultMetadata;
+import org.roaringbitmap.RoaringBitmap;
+
+
+public abstract class BaseBooleanAssertionTransformFunction extends 
BaseTransformFunction {
+  private TransformFunction _transformFunction;
+
+  @Override
+  public void init(List<TransformFunction> arguments, Map<String, 
ColumnContext> columnContextMap) {
+    Preconditions.checkArgument(arguments.size() == 1, "Exact 1 argument is 
required for " + getName());
+    _transformFunction = arguments.get(0);
+  }
+
+  @Override
+  public TransformResultMetadata getResultMetadata() {
+    return BOOLEAN_SV_NO_DICTIONARY_METADATA;
+  }
+
+  @Override
+  public int[] transformToIntValuesSV(ValueBlock valueBlock) {
+    int length = valueBlock.getNumDocs();
+    initIntValuesSV(length);
+    Arrays.fill(_intValuesSV, 0);
+    int[] intValuesSV = _transformFunction.transformToIntValuesSV(valueBlock);
+    RoaringBitmap nullBitmap = null;
+    if (_nullHandlingEnabled) {
+      nullBitmap = _transformFunction.getNullBitmap(valueBlock);
+    }
+    if (nullBitmap != null) {
+      for (int docId = 0; docId < length; docId++) {
+        if (nullBitmap.contains(docId)) {
+          if (returnsTrueWhenValueIsNull()) {
+            _intValuesSV[docId] = 1;
+          }
+        } else if (valueEvaluatesToTrue(intValuesSV[docId])) {
+            _intValuesSV[docId] = 1;
+        }
+      }
+    } else {
+      for (int docId = 0; docId < length; docId++) {
+        if (valueEvaluatesToTrue(intValuesSV[docId])) {
+          _intValuesSV[docId] = 1;
+        }
+      }
+    }
+    return _intValuesSV;
+  }
+
+  protected abstract boolean returnsTrueWhenValueIsNull();
+
+  protected abstract boolean valueEvaluatesToTrue(int value);
+
+  @Override
+  public RoaringBitmap getNullBitmap(ValueBlock valueBlock) {
+    return null;
+  }
+}
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsFalseTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsFalseTransformFunction.java
new file mode 100644
index 0000000000..5a0cb4ba35
--- /dev/null
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsFalseTransformFunction.java
@@ -0,0 +1,48 @@
+/**
+ * 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.core.operator.transform.function;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.pinot.common.function.TransformFunctionType;
+import org.apache.pinot.core.operator.ColumnContext;
+
+
+public class IsFalseTransformFunction extends 
BaseBooleanAssertionTransformFunction {
+
+  @Override
+  public String getName() {
+    return TransformFunctionType.IS_FALSE.getName();
+  }
+
+  @Override
+  public void init(List<TransformFunction> arguments, Map<String, 
ColumnContext> columnContextMap) {
+    super.init(arguments, columnContextMap);
+  }
+
+  @Override
+  protected boolean returnsTrueWhenValueIsNull() {
+    return false;
+  }
+
+  @Override
+  protected boolean valueEvaluatesToTrue(int value) {
+    return value == 0;
+  }
+}
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotFalseTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotFalseTransformFunction.java
new file mode 100644
index 0000000000..3e574830f0
--- /dev/null
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotFalseTransformFunction.java
@@ -0,0 +1,48 @@
+/**
+ * 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.core.operator.transform.function;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.pinot.common.function.TransformFunctionType;
+import org.apache.pinot.core.operator.ColumnContext;
+
+
+public class IsNotFalseTransformFunction extends 
BaseBooleanAssertionTransformFunction {
+
+  @Override
+  public String getName() {
+    return TransformFunctionType.IS_NOT_TRUE.getName();
+  }
+
+  @Override
+  public void init(List<TransformFunction> arguments, Map<String, 
ColumnContext> columnContextMap) {
+    super.init(arguments, columnContextMap);
+  }
+
+  @Override
+  protected boolean returnsTrueWhenValueIsNull() {
+    return true;
+  }
+
+  @Override
+  protected boolean valueEvaluatesToTrue(int value) {
+    return value != 0;
+  }
+}
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotTrueTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotTrueTransformFunction.java
new file mode 100644
index 0000000000..bc9d8bbbc9
--- /dev/null
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsNotTrueTransformFunction.java
@@ -0,0 +1,48 @@
+/**
+ * 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.core.operator.transform.function;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.pinot.common.function.TransformFunctionType;
+import org.apache.pinot.core.operator.ColumnContext;
+
+
+public class IsNotTrueTransformFunction extends 
BaseBooleanAssertionTransformFunction {
+
+  @Override
+  public String getName() {
+    return TransformFunctionType.IS_NOT_TRUE.getName();
+  }
+
+  @Override
+  public void init(List<TransformFunction> arguments, Map<String, 
ColumnContext> columnContextMap) {
+    super.init(arguments, columnContextMap);
+  }
+
+  @Override
+  protected boolean returnsTrueWhenValueIsNull() {
+    return true;
+  }
+
+  @Override
+  protected boolean valueEvaluatesToTrue(int value) {
+    return value == 0;
+  }
+}
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsTrueTransformFunction.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsTrueTransformFunction.java
new file mode 100644
index 0000000000..68619be91c
--- /dev/null
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/IsTrueTransformFunction.java
@@ -0,0 +1,48 @@
+/**
+ * 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.core.operator.transform.function;
+
+import java.util.List;
+import java.util.Map;
+import org.apache.pinot.common.function.TransformFunctionType;
+import org.apache.pinot.core.operator.ColumnContext;
+
+
+public class IsTrueTransformFunction extends 
BaseBooleanAssertionTransformFunction {
+
+  @Override
+  public String getName() {
+    return TransformFunctionType.IS_TRUE.getName();
+  }
+
+  @Override
+  public void init(List<TransformFunction> arguments, Map<String, 
ColumnContext> columnContextMap) {
+    super.init(arguments, columnContextMap);
+  }
+
+  @Override
+  protected boolean returnsTrueWhenValueIsNull() {
+    return false;
+  }
+
+  @Override
+  protected boolean valueEvaluatesToTrue(int value) {
+    return value != 0;
+  }
+}
diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/TransformFunctionFactory.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/TransformFunctionFactory.java
index be2b54d128..49030f871f 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/TransformFunctionFactory.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/TransformFunctionFactory.java
@@ -203,6 +203,10 @@ public class TransformFunctionFactory {
     typeToImplementation.put(TransformFunctionType.GREATEST, 
GreatestTransformFunction.class);
 
     // null handling
+    typeToImplementation.put(TransformFunctionType.IS_TRUE, 
IsTrueTransformFunction.class);
+    typeToImplementation.put(TransformFunctionType.IS_NOT_TRUE, 
IsNotTrueTransformFunction.class);
+    typeToImplementation.put(TransformFunctionType.IS_FALSE, 
IsFalseTransformFunction.class);
+    typeToImplementation.put(TransformFunctionType.IS_NOT_FALSE, 
IsNotFalseTransformFunction.class);
     typeToImplementation.put(TransformFunctionType.IS_NULL, 
IsNullTransformFunction.class);
     typeToImplementation.put(TransformFunctionType.IS_NOT_NULL, 
IsNotNullTransformFunction.class);
     typeToImplementation.put(TransformFunctionType.COALESCE, 
CoalesceTransformFunction.class);
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/queries/NullHandlingEnabledQueriesTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/queries/NullHandlingEnabledQueriesTest.java
index 9830f35f7e..d38b6462d0 100644
--- 
a/pinot-core/src/test/java/org/apache/pinot/queries/NullHandlingEnabledQueriesTest.java
+++ 
b/pinot-core/src/test/java/org/apache/pinot/queries/NullHandlingEnabledQueriesTest.java
@@ -114,6 +114,40 @@ public class NullHandlingEnabledQueriesTest extends 
BaseQueriesTest {
     _rows.add(row);
   }
 
+  @DataProvider(name = "BooleanAssertionFunctions")
+  public static Object[][] getBooleanAssertionFunctionsParameters() {
+    return new Object[][]{
+        {"istrue", true, true},
+        {"istrue", false, false},
+        {"istrue", null, false},
+        {"isnottrue", true, false},
+        {"isnottrue", false, true},
+        {"isnottrue", null, true},
+        {"isfalse", true, false},
+        {"isfalse", false, true},
+        {"isfalse", null, false},
+        {"isnotfalse", true, true},
+        {"isnotfalse", false, false},
+        {"isnotfalse", null, true}
+    };
+  }
+
+  @Test(dataProvider = "BooleanAssertionFunctions")
+  public void testBooleanAssertionFunctions(String function, Boolean data, 
Boolean queryResult)
+      throws Exception {
+    initializeRows();
+    insertRow(data);
+    TableConfig tableConfig = new 
TableConfigBuilder(TableType.OFFLINE).setTableName(RAW_TABLE_NAME).build();
+    Schema schema = new 
Schema.SchemaBuilder().addSingleValueDimension(COLUMN1, 
FieldSpec.DataType.BOOLEAN).build();
+    setUpSegments(tableConfig, schema);
+    String query = String.format("SELECT %s(%s) FROM testTable LIMIT 1", 
function, COLUMN1);
+
+    BrokerResponseNative brokerResponse = getBrokerResponse(query, 
QUERY_OPTIONS);
+
+    ResultTable resultTable = brokerResponse.getResultTable();
+    assertEquals(resultTable.getRows().get(0)[0], queryResult);
+  }
+
   @Test
   public void testGroupByOrderByNullsLastUsingOrdinal()
       throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to