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

jhyde pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit f7ad9093f40b813a5ee287ba71c1fe1c234a60c5
Author: zstan <[email protected]>
AuthorDate: Thu May 11 16:26:41 2023 +0300

    [CALCITE-5699] Negated posix regex expressions throw NullPointerException 
when applied to NULL values
    
    Close apache/calcite#3197
---
 .../java/org/apache/calcite/test/BabelTest.java    | 18 ++++++++
 babel/src/test/resources/sql/postgresql.iq         | 51 ++++++++++++++++++++++
 .../calcite/adapter/enumerable/RexImpTable.java    | 10 +++--
 3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/babel/src/test/java/org/apache/calcite/test/BabelTest.java 
b/babel/src/test/java/org/apache/calcite/test/BabelTest.java
index afe05ed2ba..8bed1b28c4 100644
--- a/babel/src/test/java/org/apache/calcite/test/BabelTest.java
+++ b/babel/src/test/java/org/apache/calcite/test/BabelTest.java
@@ -109,6 +109,24 @@ class BabelTest {
     }
   }
 
+  @Test void testPosixRegex() {
+    final SqlValidatorFixture f = Fixtures.forValidator()
+        .withParserConfig(p -> 
p.withParserFactory(SqlBabelParserImpl.FACTORY));
+    f.withSql("select null !~ 'ab[cd]'").ok();
+    f.withSql("select 'abcd' !~ null").ok();
+    f.withSql("select null !~ null").ok();
+    f.withSql("select null !~* 'ab[cd]'").ok();
+    f.withSql("select 'abcd' !~* null").ok();
+    f.withSql("select null !~* null").ok();
+    f.withSql("select null ~* null").ok();
+    f.withSql("select 'abcd' ~* null").ok();
+    f.withSql("select null ~* 'ab[cd]'").ok();
+    f.withSql("select null ~ null").ok();
+    f.withSql("select 'abcd' ~ null").ok();
+    f.withSql("select null ~ 'ab[cd]'").ok();
+    f.withSql("select 'abcd' !~* 'ab[CD]'").ok();
+  }
+
   /** Tests that you can run tests via {@link Fixtures}. */
   @Test void testFixtures() {
     final SqlValidatorFixture v = Fixtures.forValidator();
diff --git a/babel/src/test/resources/sql/postgresql.iq 
b/babel/src/test/resources/sql/postgresql.iq
index b69f8b0fe1..4cc2661154 100644
--- a/babel/src/test/resources/sql/postgresql.iq
+++ b/babel/src/test/resources/sql/postgresql.iq
@@ -62,3 +62,54 @@ select to_char(timestamp '2022-06-03 12:15:48.678', 
'YYYY-MM-DD HH24:MI:SS.MS TZ
 EXPR$0
 2022-06-03 12:15:48.678
 !ok
+
+# -----------------------------------------------------------------------------
+# Posix regex
+
+# [CALCITE-5699] NPE in Posix regex
+SELECT null !~ 'ab[cd]' AS x;
+X
+null
+!ok
+
+SELECT 'abcd' !~ null AS x;
+X
+null
+!ok
+
+SELECT null !~ null AS x;
+X
+null
+!ok
+
+SELECT null !~* 'ab[cd]' AS x;
+X
+null
+!ok
+
+SELECT 'abcd' !~* null AS x;
+X
+null
+!ok
+
+SELECT null !~* null AS x;
+X
+null
+!ok
+
+SELECT 'abe' !~ 'ab[cd]' AS x;
+X
+true
+!ok
+
+SELECT 'abd' !~ 'ab[cd]' AS x;
+X
+false
+!ok
+
+SELECT 'abd' ~ 'ab[cd]' AS x;
+X
+true
+!ok
+
+# End postgresql.iq
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 0d5090a93a..6bc1dd18e7 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -3216,7 +3216,7 @@ public class RexImpTable {
     private final AbstractRexCallImplementor implementor;
 
     private NotImplementor(AbstractRexCallImplementor implementor) {
-      super("not", null, false);
+      super("not", implementor.getNullPolicy(), false);
       this.implementor = implementor;
     }
 
@@ -3489,9 +3489,13 @@ public class RexImpTable {
       return variableName;
     }
 
+    @Nullable NullPolicy getNullPolicy() {
+      return nullPolicy;
+    }
+
     /** Figures out conditional expression according to NullPolicy. */
     Expression getCondition(final List<Expression> argIsNullList) {
-      if (argIsNullList.size() == 0
+      if (argIsNullList.isEmpty()
           || nullPolicy == null
           || nullPolicy == NullPolicy.NONE) {
         return FALSE_EXPR;
@@ -3618,7 +3622,7 @@ public class RexImpTable {
             .map(AbstractRexCallImplementor::unboxExpression)
             .collect(Collectors.toList());
       }
-      if (nullPolicy == NullPolicy.ARG0 && argValueList.size() > 0) {
+      if (nullPolicy == NullPolicy.ARG0 && !argValueList.isEmpty()) {
         final Expression unboxArg0 = unboxExpression(unboxValueList.get(0));
         unboxValueList.set(0, unboxArg0);
       }

Reply via email to