Changeset: 606a0bfbc16f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=606a0bfbc16f
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        clients/Tests/exports.stable.out
        gdk/gdk_calc.c
        gdk/gdk_calc.h
        monetdb5/modules/mal/01_batcalc.mal
        monetdb5/modules/mal/01_batcalc.mal.sh
        monetdb5/modules/mal/01_calc.mal
        monetdb5/modules/mal/01_calc.mal.sh
        monetdb5/modules/mal/batcalc.c
        monetdb5/modules/mal/calc.c
        sql/backends/monet5/sql_statement.c
Branch: default
Log Message:

Implemented a nils_false argument for (bat)calc.between.
If set, nil values result in a false result instead of a nil result.


diffs (truncated from 457 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -6108,14 +6108,14 @@ stdout of test 'MAL-signatures` in direc
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], s:bat[:oid], 
scale:int):dbl ",        "CMDcalcavg;",  "average of non-nil values of B"       
 ]
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], scale:int) (X_0:dbl, 
X_1:lng) ",      "CMDcalcavg;",  "average and number of non-nil values of B"    
 ]
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], scale:int):dbl ",     
"CMDcalcavg;",  "average of non-nil values of B with candidates list"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] ",      
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with candidate 
list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, sym:bit, linc:bit, hinc:bit):bat[:bit] ",   
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] 
",        "CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with 
candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], sym:bit, linc:bit, hinc:bit):bat[:bit] ",     
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] 
",        "CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with 
candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, sym:bit, linc:bit, hinc:bit):bat[:bit] ",     
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, 
hinc:bit):bat[:bit] ",  "CMDbatBETWEEN;",       "B between V1 and V2 (or vice 
versa) with candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], sym:bit, linc:bit, hinc:bit):bat[:bit] ",       
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",      "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, sym:bit, linc:bit, hinc:bit, nils_false:bit):bat[:bit] ",   
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",        "CMDbatBETWEEN;",       "B between V1 and 
V2 (or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",     "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",        "CMDbatBETWEEN;",       "B between V1 and 
V2 (or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",     "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",  "CMDbatBETWEEN;",       "B between V1 and V2 (or 
vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",       "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
 [ "batcalc",   "bit",  "pattern batcalc.bit(b:bat[:bit]):bat[:bit] ",  
"CMDconvertsignal_bit;",        "cast from bit to bit, signal error on 
overflow"        ]
 [ "batcalc",   "bit",  "pattern batcalc.bit(b:bat[:bit], 
s:bat[:oid]):bat[:bit] ",     "CMDconvertsignal_bit;",        "cast from bit to 
bit with candidates list, signal error on overflow"   ]
 [ "batcalc",   "bit",  "pattern batcalc.bit(b:bat[:bte]):bat[:bit] ",  
"CMDconvertsignal_bit;",        "cast from bte to bit, signal error on 
overflow"        ]
@@ -10054,7 +10054,7 @@ stdout of test 'MAL-signatures` in direc
 [ "calc",      "and",  "pattern calc.and(v1:int, v2:int):int ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
 [ "calc",      "and",  "pattern calc.and(v1:lng, v2:lng):lng ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
 [ "calc",      "and",  "pattern calc.and(v1:sht, v2:sht):sht ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
-[ "calc",      "between",      "pattern calc.between(b:any_1, lo:any_1, 
hi:any_1, sym:bit, linc:bit, hinc:bit):bit ",  "CMDvarBETWEEN;",       "B 
between LO and HI inclusive" ]
+[ "calc",      "between",      "pattern calc.between(b:any_1, lo:any_1, 
hi:any_1, sym:bit, linc:bit, hinc:bit, nils_false:bit):bit ",  
"CMDvarBETWEEN;",       "B between LO and HI inclusive" ]
 [ "calc",      "bit",  "pattern calc.bit(v:bit):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
 [ "calc",      "bit",  "pattern calc.bit(v:bte):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
 [ "calc",      "bit",  "pattern calc.bit(v:dbl):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -8642,14 +8642,14 @@ stdout of test 'MAL-signatures` in direc
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], s:bat[:oid], 
scale:int):dbl ",        "CMDcalcavg;",  "average of non-nil values of B"       
 ]
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], scale:int) (X_0:dbl, 
X_1:lng) ",      "CMDcalcavg;",  "average and number of non-nil values of B"    
 ]
 [ "batcalc",   "avg",  "pattern batcalc.avg(b:bat[:sht], scale:int):dbl ",     
"CMDcalcavg;",  "average of non-nil values of B with candidates list"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] ",      
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with candidate 
list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, sym:bit, linc:bit, hinc:bit):bat[:bit] ",   
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] 
",        "CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with 
candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], sym:bit, linc:bit, hinc:bit):bat[:bit] ",     
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit):bat[:bit] 
",        "CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa) with 
candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, sym:bit, linc:bit, hinc:bit):bat[:bit] ",     
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, 
hinc:bit):bat[:bit] ",  "CMDbatBETWEEN;",       "B between V1 and V2 (or vice 
versa) with candidate list"       ]
-[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], sym:bit, linc:bit, hinc:bit):bat[:bit] ",       
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",      "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:any_1, sym:bit, linc:bit, hinc:bit, nils_false:bit):bat[:bit] ",   
"CMDbatBETWEEN;",       "B between V1 and V2 (or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",        "CMDbatBETWEEN;",       "B between V1 and 
V2 (or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:any_1, v2:bat[:any_1], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",     "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",        "CMDbatBETWEEN;",       "B between V1 and 
V2 (or vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:any_1, sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",     "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], s:bat[:oid], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",  "CMDbatBETWEEN;",       "B between V1 and V2 (or 
vice versa) with candidate list"       ]
+[ "batcalc",   "between",      "pattern batcalc.between(b:bat[:any_1], 
v1:bat[:any_1], v2:bat[:any_1], sym:bit, linc:bit, hinc:bit, 
nils_false:bit):bat[:bit] ",       "CMDbatBETWEEN;",       "B between V1 and V2 
(or vice versa)"   ]
 [ "batcalc",   "between",      "pattern batcalc.between(b:bat[:hge], 
lo:bat[:hge], hi:bat[:hge]):bat[:bit] ",  "CMDbatBETWEEN;",       "B between LO 
and HI inclusive, nil border is (minus) infinity" ]
 [ "batcalc",   "between",      "pattern batcalc.between(b:bat[:hge], 
lo:bat[:hge], hi:bat[:hge], s:bat[:oid]):bat[:bit] ",     "CMDbatBETWEEN;",     
  "B between LO and HI inclusive with candidates list, nil border is (minus) 
infinity"    ]
 [ "batcalc",   "between",      "pattern batcalc.between(b:bat[:hge], 
lo:bat[:hge], hi:hge):bat[:bit] ",        "CMDbatBETWEEN;",       "B between LO 
and HI inclusive, nil border is (minus) infinity" ]
@@ -14206,7 +14206,7 @@ stdout of test 'MAL-signatures` in direc
 [ "calc",      "and",  "pattern calc.and(v1:int, v2:int):int ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
 [ "calc",      "and",  "pattern calc.and(v1:lng, v2:lng):lng ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
 [ "calc",      "and",  "pattern calc.and(v1:sht, v2:sht):sht ",        
"CMDvarAND;",   "Return V1 AND V2"      ]
-[ "calc",      "between",      "pattern calc.between(b:any_1, lo:any_1, 
hi:any_1, sym:bit, linc:bit, hinc:bit):bit ",  "CMDvarBETWEEN;",       "B 
between LO and HI inclusive" ]
+[ "calc",      "between",      "pattern calc.between(b:any_1, lo:any_1, 
hi:any_1, sym:bit, linc:bit, hinc:bit, nils_false:bit):bit ",  
"CMDvarBETWEEN;",       "B between LO and HI inclusive" ]
 [ "calc",      "bit",  "pattern calc.bit(v:bit):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
 [ "calc",      "bit",  "pattern calc.bit(v:bte):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
 [ "calc",      "bit",  "pattern calc.bit(v:dbl):bit ", "CMDvarCONVERT;",       
"Cast VALUE to bit"     ]
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -27,10 +27,10 @@ BAT *BATcalcaddcst(BAT *b, const ValReco
 BAT *BATcalcand(BAT *b1, BAT *b2, BAT *s);
 BAT *BATcalcandcst(BAT *b, const ValRecord *v, BAT *s);
 gdk_return BATcalcavg(BAT *b, BAT *s, dbl *avg, BUN *vals, int scale);
-BAT *BATcalcbetween(BAT *b, BAT *lo, BAT *hi, BAT *s, bool symmetric, bool 
linc, bool hinc);
-BAT *BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi, BAT *s, bool 
symmetric, bool linc, bool hinc);
-BAT *BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi, BAT *s, bool 
symmetric, bool linc, bool hinc);
-BAT *BATcalcbetweencstcst(BAT *b, const ValRecord *lo, const ValRecord *hi, 
BAT *s, bool symmetric, bool linc, bool hinc);
+BAT *BATcalcbetween(BAT *b, BAT *lo, BAT *hi, BAT *s, bool symmetric, bool 
linc, bool hinc, bool nils_false);
+BAT *BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi, BAT *s, bool 
symmetric, bool linc, bool hinc, bool nils_false);
+BAT *BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi, BAT *s, bool 
symmetric, bool linc, bool hinc, bool nils_false);
+BAT *BATcalcbetweencstcst(BAT *b, const ValRecord *lo, const ValRecord *hi, 
BAT *s, bool symmetric, bool linc, bool hinc, bool nils_false);
 BAT *BATcalccmp(BAT *b1, BAT *b2, BAT *s);
 BAT *BATcalccmpcst(BAT *b, const ValRecord *v, BAT *s);
 BAT *BATcalccstadd(const ValRecord *v, BAT *b, BAT *s, int tp, bool 
abort_on_error);
@@ -354,7 +354,7 @@ ValPtr VALset(ValPtr v, int t, void *p);
 gdk_return VARcalcabsolute(ValPtr ret, const ValRecord *v);
 gdk_return VARcalcadd(ValPtr ret, const ValRecord *lft, const ValRecord *rgt, 
bool abort_on_error);
 gdk_return VARcalcand(ValPtr ret, const ValRecord *lft, const ValRecord *rgt);
-gdk_return VARcalcbetween(ValPtr ret, const ValRecord *v, const ValRecord *lo, 
const ValRecord *hi, bool symmetric, bool linc, bool hinc);
+gdk_return VARcalcbetween(ValPtr ret, const ValRecord *v, const ValRecord *lo, 
const ValRecord *hi, bool symmetric, bool linc, bool hinc, bool nils_false);
 gdk_return VARcalccmp(ValPtr ret, const ValRecord *lft, const ValRecord *rgt);
 gdk_return VARcalcdecr(ValPtr ret, const ValRecord *v, bool abort_on_error);
 gdk_return VARcalcdiv(ValPtr ret, const ValRecord *lft, const ValRecord *rgt, 
bool abort_on_error);
diff --git a/gdk/gdk_calc.c b/gdk/gdk_calc.c
--- a/gdk/gdk_calc.c
+++ b/gdk/gdk_calc.c
@@ -12758,13 +12758,15 @@ VARcalcrsh(ValPtr ret, const ValRecord *
 /* between (any "linear" type) */
 
 #define BETWEEN(v, lo, hi, TYPE)                                       \
-       (is_##TYPE##_nil(v) || is_##TYPE##_nil(lo) || is_##TYPE##_nil(hi) ? \
-        (nils++, bit_nil) :                                            \
-        (bit) ((((lo) < (v) || (linc && (lo) == (v))) &&               \
-                ((v) < (hi) || (hinc && (v) == (hi)))) ||              \
-               (symmetric &&                                                   
\
-                ((hi) < (v) || (hinc && (hi) == (v))) &&               \
-                ((v) < (lo) || (linc && (v) == (lo))))))
+       (is_##TYPE##_nil(v)                                             \
+        ? nils_false ? 0 : (nils++, bit_nil)                           \
+        : (is_##TYPE##_nil(lo) || is_##TYPE##_nil(hi)                  \
+           ? (nils++, bit_nil)                                         \
+           : (bit) ((((lo) < (v) || (linc && (lo) == (v))) &&          \
+                     ((v) < (hi) || (hinc && (v) == (hi)))) ||         \
+                    (symmetric &&                                      \
+                     ((hi) < (v) || (hinc && (hi) == (v))) &&          \
+                     ((v) < (lo) || (linc && (v) == (lo)))))))
 
 #define BETWEEN_LOOP_TYPE(TYPE)                                                
\
        do {                                                            \
@@ -12789,7 +12791,7 @@ BATcalcbetween_intern(const void *src, i
                      int tp, BUN cnt, BUN start, BUN end,
                      const oid *restrict cand, const oid *candend,
                      oid seqbase, bool symmetric,
-                     bool linc, bool hinc, const char *func)
+                     bool linc, bool hinc, bool nils_false, const char *func)
 {
        BAT *bn;
        BUN nils = 0;
@@ -12860,10 +12862,18 @@ BATcalcbetween_intern(const void *src, i
                        p3 = hp3
                                ? (const void *) (hp3 + VarHeapVal(hi, k, wd3))
                                : (const void *) ((const char *) hi + hoff);
-                       if (p1 == NULL || p2 == NULL || p3 == NULL ||
-                           (*atomcmp)(p1, nil) == 0 ||
-                           (*atomcmp)(p2, nil) == 0 ||
-                           (*atomcmp)(p3, nil) == 0) {
+                       if (p1 == NULL || p2 == NULL || p3 == NULL) {
+                               nils++;
+                               dst[l] = bit_nil;
+                       } else if ((*atomcmp)(p1, nil) == 0) {
+                               if (nils_false)
+                                       dst[l] = 0;
+                               else {
+                                       nils++;
+                                       dst[l] = bit_nil;
+                               }
+                       } else if ((*atomcmp)(p2, nil) == 0 ||
+                                  (*atomcmp)(p3, nil) == 0) {
                                nils++;
                                dst[l] = bit_nil;
                        } else {
@@ -12898,7 +12908,7 @@ BATcalcbetween_intern(const void *src, i
 
 BAT *
 BATcalcbetween(BAT *b, BAT *lo, BAT *hi, BAT *s, bool symmetric,
-              bool linc, bool hinc)
+              bool linc, bool hinc, bool nils_false)
 {
        BAT *bn;
        BUN start, end, cnt;
@@ -12920,7 +12930,9 @@ BATcalcbetween(BAT *b, BAT *lo, BAT *hi,
            BATtvoid(hi)) {
                bit res;
 
-               if (!BATtdense(b) || !BATtdense(lo) || !BATtdense(hi))
+               if (!BATtdense(b))
+                       res = nils_false ? 0 : bit_nil;
+               else if (!BATtdense(lo) || !BATtdense(hi))
                        res = bit_nil;
                else
                        res = (bit)
@@ -12950,14 +12962,14 @@ BATcalcbetween(BAT *b, BAT *lo, BAT *hi,
                                   b->ttype, cnt,
                                   start, end, cand, candend,
                                   b->hseqbase, symmetric, linc, hinc,
-                                  "BATcalcbetween");
+                                  nils_false, "BATcalcbetween");
 
        return bn;
 }
 
 BAT *
 BATcalcbetweencstcst(BAT *b, const ValRecord *lo, const ValRecord *hi, BAT *s,
-                    bool symmetric, bool linc, bool hinc)
+                    bool symmetric, bool linc, bool hinc, bool nils_false)
 {
        BAT *bn;
        BUN start, end, cnt;
@@ -12981,14 +12993,15 @@ BATcalcbetweencstcst(BAT *b, const ValRe
                                   b->ttype, cnt,
                                   start, end, cand, candend,
                                   b->hseqbase, symmetric,
-                                  linc, hinc, "BATcalcbetweencstcst");
+                                  linc, hinc, nils_false,
+                                  "BATcalcbetweencstcst");
 
        return bn;
 }
 
 BAT *
 BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi, BAT *s,
-                    bool symmetric, bool linc, bool hinc)
+                    bool symmetric, bool linc, bool hinc, bool nils_false)
 {
        BAT *bn;
        BUN start, end, cnt;
@@ -13017,14 +13030,15 @@ BATcalcbetweenbatcst(BAT *b, BAT *lo, co
                                   b->ttype, cnt,
                                   start, end, cand, candend,
                                   b->hseqbase, symmetric,
-                                  linc, hinc, "BATcalcbetweenbatcst");
+                                  linc, hinc, nils_false,
+                                  "BATcalcbetweenbatcst");
 
        return bn;
 }
 
 BAT *
 BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi, BAT *s,
-                    bool symmetric, bool linc, bool hinc)
+                    bool symmetric, bool linc, bool hinc, bool nils_false)
 {
        BAT *bn;
        BUN start, end, cnt;
@@ -13053,14 +13067,16 @@ BATcalcbetweencstbat(BAT *b, const ValRe
                                   b->ttype, cnt,
                                   start, end, cand, candend,
                                   b->hseqbase, symmetric,
-                                  linc, hinc, "BATcalcbetweencstbat");
+                                  linc, hinc, nils_false,
+                                  "BATcalcbetweencstbat");
 
        return bn;
 }
 
 gdk_return
 VARcalcbetween(ValPtr ret, const ValRecord *v, const ValRecord *lo,
-              const ValRecord *hi, bool symmetric, bool linc, bool hinc)
+              const ValRecord *hi, bool symmetric, bool linc, bool hinc,
+              bool nils_false)
 {
        BUN nils = 0;           /* to make reusing BETWEEN macro easier */
        int t;
@@ -13107,9 +13123,10 @@ VARcalcbetween(ValPtr ret, const ValReco
        default:
                nil = ATOMnilptr(t);
                atomcmp = ATOMcompare(t);
-               if (atomcmp(VALptr(v), nil) == 0 ||
-                   atomcmp(VALptr(lo), nil) == 0 ||
-                   atomcmp(VALptr(hi), nil) == 0)
+               if (atomcmp(VALptr(v), nil) == 0)
+                       ret->val.btval = nils_false ? 0 : bit_nil;
+               else if (atomcmp(VALptr(lo), nil) == 0 ||
+                        atomcmp(VALptr(hi), nil) == 0)
                        ret->val.btval = bit_nil;
                else {
                        int c;
diff --git a/gdk/gdk_calc.h b/gdk/gdk_calc.h
--- a/gdk/gdk_calc.h
+++ b/gdk/gdk_calc.h
@@ -80,11 +80,11 @@ gdk_export BAT *BATcalccstne(const ValRe
 gdk_export BAT *BATcalccmp(BAT *b1, BAT *b2, BAT *s);
 gdk_export BAT *BATcalccmpcst(BAT *b, const ValRecord *v, BAT *s);
 gdk_export BAT *BATcalccstcmp(const ValRecord *v, BAT *b, BAT *s);
-gdk_export BAT *BATcalcbetween(BAT *b, BAT *lo, BAT *hi, BAT *s, bool 
symmetric, bool linc, bool hinc);
-gdk_export BAT *BATcalcbetweencstcst(BAT *b, const ValRecord *lo, const 
ValRecord *hi, BAT *s, bool symmetric, bool linc, bool hinc);
-gdk_export BAT *BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi, BAT 
*s, bool symmetric, bool linc, bool hinc);
-gdk_export BAT *BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi, BAT 
*s, bool symmetric, bool linc, bool hinc);
-gdk_export gdk_return VARcalcbetween(ValPtr ret, const ValRecord *v, const 
ValRecord *lo, const ValRecord *hi, bool symmetric, bool linc, bool hinc);
+gdk_export BAT *BATcalcbetween(BAT *b, BAT *lo, BAT *hi, BAT *s, bool 
symmetric, bool linc, bool hinc, bool nils_false);
+gdk_export BAT *BATcalcbetweencstcst(BAT *b, const ValRecord *lo, const 
ValRecord *hi, BAT *s, bool symmetric, bool linc, bool hinc, bool nils_false);
+gdk_export BAT *BATcalcbetweenbatcst(BAT *b, BAT *lo, const ValRecord *hi, BAT 
*s, bool symmetric, bool linc, bool hinc, bool nils_false);
+gdk_export BAT *BATcalcbetweencstbat(BAT *b, const ValRecord *lo, BAT *hi, BAT 
*s, bool symmetric, bool linc, bool hinc, bool nils_false);
+gdk_export gdk_return VARcalcbetween(ValPtr ret, const ValRecord *v, const 
ValRecord *lo, const ValRecord *hi, bool symmetric, bool linc, bool hinc, bool 
nils_false);
 gdk_export BAT *BATcalcifthenelse(BAT *b, BAT *b1, BAT *b2);
 gdk_export BAT *BATcalcifthenelsecst(BAT *b, BAT *b1, const ValRecord *c2);
 gdk_export BAT *BATcalcifthencstelse(BAT *b, const ValRecord *c1, BAT *b2);
diff --git a/monetdb5/modules/mal/01_batcalc.mal 
b/monetdb5/modules/mal/01_batcalc.mal
--- a/monetdb5/modules/mal/01_batcalc.mal
+++ b/monetdb5/modules/mal/01_batcalc.mal
@@ -23100,28 +23100,28 @@ address CMDbatCMP
 comment "Return -1/0/1 if V </==/> B with candidates list";
 
 
-pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:bat[:any_1],sym:bit,linc:bit,hinc:bit) 
:bat[:bit]
+pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:bat[:any_1],sym:bit,linc:bit,hinc:bit,nils_false:bit)
 :bat[:bit]
 address CMDbatBETWEEN
 comment "B between V1 and V2 (or vice versa)";
-pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:bat[:any_1],s:bat[:oid],sym:bit,linc:bit,hinc:bit)
 :bat[:bit]
+pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:bat[:any_1],s:bat[:oid],sym:bit,linc:bit,hinc:bit,nils_false:bit)
 :bat[:bit]
 address CMDbatBETWEEN
 comment "B between V1 and V2 (or vice versa) with candidate list";
-pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:any_1,sym:bit,linc:bit,hinc:bit) 
:bat[:bit]
+pattern 
between(b:bat[:any_1],v1:bat[:any_1],v2:any_1,sym:bit,linc:bit,hinc:bit,nils_false:bit)
 :bat[:bit]
 address CMDbatBETWEEN
 comment "B between V1 and V2 (or vice versa)";
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to