Changeset: 0acef3664468 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0acef3664468
Modified Files:
        monetdb5/modules/mal/pcre.c
        sql/test/miscellaneous/Tests/simple_selects.stable.out
Branch: default
Log Message:

handle null like null etc beter.


diffs (137 lines):

diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -1609,7 +1609,9 @@ PCRElike4(bit *ret, const str *s, const 
 
        if (!r) {
                assert(ppat);
-               if (strNil(ppat)) {
+               if (strNil(*pat) || strNil(*s)) {
+                       *ret = bit_nil;
+               } else if (strNil(ppat)) {
                        *ret = FALSE;
                        if (*isens) {
                                if (mystrcasecmp(*s, *pat) == 0)
@@ -1654,7 +1656,7 @@ PCREnotlike3(bit *ret, const str *s, con
        bit r;
 
        rethrow("str.not_like", tmp, PCRElike3(&r, s, pat, esc));
-       *ret = !r;
+       *ret = r==bit_nil?bit_nil:!r;
        return MAL_SUCCEED;
 }
 
@@ -1665,7 +1667,7 @@ PCREnotlike2(bit *ret, const str *s, con
        bit r;
 
        rethrow("str.not_like", tmp, PCRElike2(&r, s, pat));
-       *ret = !r;
+       *ret = r==bit_nil?bit_nil:!r;
        return MAL_SUCCEED;
 }
 
@@ -1692,7 +1694,7 @@ PCREnotilike3(bit *ret, const str *s, co
        bit r;
 
        rethrow("str.not_ilike", tmp, PCREilike3(&r, s, pat, esc));
-       *ret = !r;
+       *ret = r==bit_nil?bit_nil:!r;
        return MAL_SUCCEED;
 }
 
@@ -1703,7 +1705,7 @@ PCREnotilike2(bit *ret, const str *s, co
        bit r;
 
        rethrow("str.not_ilike", tmp, PCREilike2(&r, s, pat));
-       *ret = !r;
+       *ret = r==bit_nil?bit_nil:!r;
        return MAL_SUCCEED;
 }
 
@@ -1734,7 +1736,10 @@ BATPCRElike3(bat *ret, const bat *bid, c
                br = (bit*)Tloc(r, 0);
                strsi = bat_iterator(strs);
 
-               if (strNil(ppat)) {
+               if (strNil(*pat)) {
+                       BATloop(strs, p, q) 
+                               br[i] = bit_nil;
+               } else if (strNil(ppat)) {
                        BATloop(strs, p, q) {
                                const char *s = (str)BUNtvar(strsi, p);
 
@@ -1908,6 +1913,7 @@ PCRElikeselect2(bat *ret, const bat *bid
        char *ppat = NULL;
        bool use_re = false;
        bool use_strcmp = false;
+       bool empty = false;
 
        if ((b = BATdescriptor(*bid)) == NULL) {
                throw(MAL, "algebra.likeselect", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
@@ -1918,7 +1924,9 @@ PCRElikeselect2(bat *ret, const bat *bid
        }
 
        /* no escape, try if a simple list of keywords works */
-       if (is_strcmpable(*pat, *esc)) {
+       if (strNil(*pat)) {
+               empty = true;
+       } else if (is_strcmpable(*pat, *esc)) {
                use_re = true;
                use_strcmp = true;
        } else if (re_simple(*pat, **esc == '\200' ? 0 : (unsigned char) 
**esc)) {
@@ -1953,7 +1961,10 @@ PCRElikeselect2(bat *ret, const bat *bid
                res = re_likeselect(&bn, b, s, *pat, (bool) *caseignore, (bool) 
*anti, use_strcmp, **esc == '\200' ? 0 : (unsigned char) **esc);
        } else if (ppat == NULL) {
                /* no pattern and no special characters: can use normal select 
*/
-               bn = BATselect(b, s, *pat, NULL, true, true, *anti);
+               if (empty) 
+                       bn = BATdense(0, 0, 0);
+               else
+                       bn = BATselect(b, s, *pat, NULL, true, true, *anti);
                if (bn == NULL)
                        res = createException(MAL, "algebra.likeselect", 
GDK_EXCEPTION);
                else
diff --git a/sql/test/miscellaneous/Tests/simple_selects.stable.out 
b/sql/test/miscellaneous/Tests/simple_selects.stable.out
--- a/sql/test/miscellaneous/Tests/simple_selects.stable.out
+++ b/sql/test/miscellaneous/Tests/simple_selects.stable.out
@@ -305,6 +305,40 @@ stdout of test 'simple_selects` in direc
 % clob # type
 % 0 # length
 [ NULL ]
+#select 'a' like null, null like 'a', null like null, 'a' ilike null, null 
ilike 'a', null ilike null,
+#       'a' not like null, null not like 'a', null not like null, 'a' not 
ilike null, null not ilike 'a', null not ilike null; --all NULL
+% .,   .,      .,      .,      .,      .,      .,      .,      .,      .,      
.,      . # table_name
+% %1,  %2,     %3,     %4,     %5,     %6,     %7,     %10,    %11,    %12,    
%13,    %14 # name
+% boolean,     boolean,        boolean,        boolean,        boolean,        
boolean,        boolean,        boolean,        boolean,        boolean,        
boolean,        boolean # type
+% 5,   5,      5,      5,      5,      5,      5,      5,      5,      5,      
5,      5 # length
+[ NULL,        NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
NULL,   NULL,   NULL    ]
+#create table x (x varchar(32));
+#insert into x values (null), ('a');
+[ 2    ]
+#select x like null, null like x, null like null, x ilike null, null ilike x, 
null ilike null,
+#       x not like null, null not like x, null not like null, x not ilike 
null, null not ilike x, null not ilike null from x;
+% sys.,        .,      .,      sys.,   .,      .,      sys.,   .,      .,      
sys.,   .,      . # table_name
+% %1,  %2,     %3,     %4,     %5,     %6,     %7,     %10,    %11,    %12,    
%13,    %14 # name
+% boolean,     boolean,        boolean,        boolean,        boolean,        
boolean,        boolean,        boolean,        boolean,        boolean,        
boolean,        boolean # type
+% 5,   5,      5,      5,      5,      5,      5,      5,      5,      5,      
5,      5 # length
+#select x like x, x ilike x, x not like x, x not ilike x from x;
+% sys.,        sys.,   sys.,   sys. # table_name
+% %1,  %2,     %3,     %4 # name
+% boolean,     boolean,        boolean,        boolean # type
+% 5,   5,      5,      5 # length
+[ NULL,        NULL,   NULL,   NULL    ]
+[ true,        true,   false,  false   ]
+#select x1.x from x x1 inner join x x2 on x1.x not like x2.x; --empty
+% sys.x1 # table_name
+% x # name
+% varchar # type
+% 0 # length
+#select i from (values (1),(2),(3),(NULL)) as integers(i) where not cast(i as 
varchar(32)) like null; --empty
+% .integers # table_name
+% i # name
+% tinyint # type
+% 1 # length
+#drop table x;
 
 # 17:31:38 >  
 # 17:31:38 >  "Done."
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to