Changeset: 028a8ee2320f for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/028a8ee2320f
Modified Files:
        gdk/gdk_bat.c
        gdk/gdk_batop.c
        gdk/gdk_select.c
Branch: use_min_max_prop
Log Message:

Do more checking that min/max bounds and not null are respected.


diffs (truncated from 555 to 300 lines):

diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1205,6 +1205,7 @@ BUNappendmulti(BAT *b, const void *value
                if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL &&
                    VALcopy(&maxprop, prop) != NULL)
                        maxbound = VALptr(&maxprop);
+               const bool notnull = BATgetprop_nolock(b, GDK_NOT_NULL) != NULL;
                MT_lock_unset(&b->theaplock);
                const void *minvalp = NULL, *maxvalp = NULL;
                if (minpos != BUN_NONE)
@@ -1216,13 +1217,20 @@ BUNappendmulti(BAT *b, const void *value
                        for (BUN i = 0; i < count; i++) {
                                gdk_return rc;
                                t = ((void **) values)[i];
-                               if (minbound &&
-                                   ATOMcmp(b->ttype, t, minbound) < 0) {
+                               bool isnil = atomcmp(t, atomnil) == 0;
+                               if (notnull && isnil) {
+                                       assert(0);
+                                       GDKerror("NULL value not within 
bounds\n");
+                                       rc = GDK_FAIL;
+                               } else if (minbound &&
+                                          !isnil &&
+                                          atomcmp(t, minbound) < 0) {
                                        assert(0);
                                        GDKerror("value not within bounds\n");
                                        rc = GDK_FAIL;
                                } else if (maxbound &&
-                                          ATOMcmp(b->ttype, t, maxbound) >= 0) 
{
+                                          !isnil &&
+                                          atomcmp(t, maxbound) >= 0) {
                                        assert(0);
                                        GDKerror("value not within bounds\n");
                                        rc = GDK_FAIL;
@@ -1250,7 +1258,7 @@ BUNappendmulti(BAT *b, const void *value
                                        if (maxpos != BUN_NONE)
                                                maxvalp = BUNtvar(bi, maxpos);
                                }
-                               if (atomcmp(t, atomnil) != 0) {
+                               if (!isnil) {
                                        if (p == 0) {
                                                minpos = maxpos = 0;
                                                minvalp = maxvalp = t;
@@ -1488,6 +1496,8 @@ BUNinplacemulti(BAT *b, const oid *posit
        BUN prv, nxt;
        const void *val;
        bool locked = false;
+       int (*atomcmp) (const void *, const void *) = ATOMcompare(b->ttype);
+       const void *atomnil = ATOMnilptr(b->ttype);
 
        /* zap alignment info */
        if (!force && (b->batRestricted != BAT_WRITE || b->batSharecnt > 0)) {
@@ -1505,6 +1515,7 @@ BUNinplacemulti(BAT *b, const oid *posit
        if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL &&
            VALcopy(&maxprop, prop) != NULL)
                maxbound = VALptr(&maxprop);
+       const bool notnull = BATgetprop_nolock(b, GDK_NOT_NULL) != NULL;
        MT_lock_unset(&b->theaplock);
        MT_rwlock_wrlock(&b->thashlock);
        for (BUN i = 0; i < count; i++) {
@@ -1513,10 +1524,17 @@ BUNinplacemulti(BAT *b, const oid *posit
                        ((const void **) values)[i] :
                        (const void *) ((const char *) values + (i << 
b->tshift));
 
-               if ((minbound &&
-                    ATOMcmp(b->ttype, t, minbound) < 0) ||
-                   (maxbound &&
-                    ATOMcmp(b->ttype, t, maxbound) >= 0)) {
+               bool isnil = atomnil && atomcmp(t, atomnil) == 0;
+               if (notnull && isnil) {
+                       assert(0);
+                       GDKerror("NULL value not within bounds\n");
+                       MT_rwlock_wrunlock(&b->thashlock);
+                       goto bailout;
+               } else if (!isnil &&
+                          ((minbound &&
+                            atomcmp(t, minbound) < 0) ||
+                           (maxbound &&
+                            atomcmp(t, maxbound) >= 0))) {
                        assert(0);
                        GDKerror("value not within bounds\n");
                        MT_rwlock_wrunlock(&b->thashlock);
@@ -1542,11 +1560,11 @@ BUNinplacemulti(BAT *b, const oid *posit
                }
 
                if (val) {
-                       if (ATOMcmp(b->ttype, val, t) == 0)
+                       if (atomcmp(val, t) == 0)
                                continue; /* nothing to do */
                        if (b->tnil &&
-                           ATOMcmp(b->ttype, val, ATOMnilptr(b->ttype)) == 0 &&
-                           ATOMcmp(b->ttype, t, ATOMnilptr(b->ttype)) != 0) {
+                           atomcmp(val, ATOMnilptr(b->ttype)) == 0 &&
+                           atomcmp(t, ATOMnilptr(b->ttype)) != 0) {
                                /* if old value is nil and new value
                                 * isn't, we're not sure anymore about
                                 * the nil property, so we must clear
@@ -1565,15 +1583,15 @@ BUNinplacemulti(BAT *b, const oid *posit
                                        locked = true;
                                }
                                if ((prop = BATgetprop_nolock(b, 
GDK_MAX_VALUE)) != NULL) {
-                                       if (ATOMcmp(b->ttype, t, 
ATOMnilptr(b->ttype)) != 0 &&
-                                           ATOMcmp(b->ttype, VALptr(prop), t) 
< 0) {
+                                       if (atomcmp(t, ATOMnilptr(b->ttype)) != 
0 &&
+                                           atomcmp(VALptr(prop), t) < 0) {
                                                /* new value is larger
                                                 * than previous
                                                 * largest */
                                                BATsetprop_nolock(b, 
GDK_MAX_VALUE, b->ttype, t);
                                                BATsetprop_nolock(b, 
GDK_MAX_POS, TYPE_oid, &(oid){p});
-                                       } else if (ATOMcmp(b->ttype, t, val) != 
0 &&
-                                                  ATOMcmp(b->ttype, 
VALptr(prop), val) == 0) {
+                                       } else if (atomcmp(t, val) != 0 &&
+                                                  atomcmp(VALptr(prop), val) 
== 0) {
                                                /* old value is equal to
                                                 * largest and new value
                                                 * is smaller (see
@@ -1587,15 +1605,15 @@ BUNinplacemulti(BAT *b, const oid *posit
                                        BATrmprop_nolock(b, GDK_MAX_POS);
                                }
                                if ((prop = BATgetprop_nolock(b, 
GDK_MIN_VALUE)) != NULL) {
-                                       if (ATOMcmp(b->ttype, t, 
ATOMnilptr(b->ttype)) != 0 &&
-                                           ATOMcmp(b->ttype, VALptr(prop), t) 
> 0) {
+                                       if (atomcmp(t, ATOMnilptr(b->ttype)) != 
0 &&
+                                           atomcmp(VALptr(prop), t) > 0) {
                                                /* new value is smaller
                                                 * than previous
                                                 * smallest */
                                                BATsetprop_nolock(b, 
GDK_MIN_VALUE, b->ttype, t);
                                                BATsetprop_nolock(b, 
GDK_MIN_POS, TYPE_oid, &(oid){p});
-                                       } else if (ATOMcmp(b->ttype, t, val) != 
0 &&
-                                                  ATOMcmp(b->ttype, 
VALptr(prop), val) <= 0) {
+                                       } else if (atomcmp(t, val) != 0 &&
+                                                  atomcmp(VALptr(prop), val) 
<= 0) {
                                                /* old value is equal to
                                                 * smallest and new
                                                 * value is larger (see
@@ -1770,7 +1788,7 @@ BUNinplacemulti(BAT *b, const oid *posit
                } else if (!b->tkey && (b->tnokey[0] == p || b->tnokey[1] == p))
                        b->tnokey[0] = b->tnokey[1] = 0;
                if (b->tnonil && ATOMstorage(b->ttype) != TYPE_msk)
-                       b->tnonil = t && ATOMcmp(b->ttype, t, 
ATOMnilptr(b->ttype)) != 0;
+                       b->tnonil = t && atomcmp(t, ATOMnilptr(b->ttype)) != 0;
                MT_lock_unset(&b->theaplock);
        }
        MT_rwlock_wrunlock(&b->thashlock);
@@ -2787,6 +2805,7 @@ BATassertProps(BAT *b)
                const void *minval = NULL;
                const void *maxbound = NULL;
                const void *minbound = NULL;
+               const bool notnull = BATgetprop_nolock(b, GDK_NOT_NULL) != NULL;
                bool seenmax = false, seenmin = false;
                bool seennil = false;
 
@@ -2823,11 +2842,12 @@ BATassertProps(BAT *b)
                         * scan */
                        /* only call compare function if we have to */
                        bool cmpprv = b->tsorted | b->trevsorted | b->tkey;
-                       bool cmpnil = b->tnonil | b->tnil;
 
                        BATloop(b, p, q) {
                                valp = BUNtail(bi, p);
                                bool isnil = cmpf(valp, nilp) == 0;
+                               assert(!isnil || !notnull);
+                               assert(!b->tnonil || !isnil);
                                assert(b->ttype != TYPE_flt || 
!isinf(*(flt*)valp));
                                assert(b->ttype != TYPE_dbl || 
!isinf(*(dbl*)valp));
                                if (minbound && !isnil) {
@@ -2848,31 +2868,19 @@ BATassertProps(BAT *b)
                                        assert(cmp <= 0);
                                        seenmin |= cmp == 0;
                                }
-                               if (prev && cmpprv) {
+                               if (cmpprv && prev) {
                                        cmp = cmpf(prev, valp);
                                        assert(!b->tsorted || cmp <= 0);
                                        assert(!b->trevsorted || cmp >= 0);
                                        assert(!b->tkey || cmp != 0);
                                }
-                               if (cmpnil) {
-                                       assert(!b->tnonil || !isnil);
-                                       if (isnil) {
-                                               /* we found a nil:
-                                                * we're done checking
-                                                * for them */
-                                               seennil = true;
-                                               cmpnil = 0;
-                                               if (!cmpprv && maxval == NULL 
&& minval == NULL) {
-                                                       /* we were
-                                                        * only
-                                                        * checking
-                                                        * for nils,
-                                                        * so nothing
-                                                        * more to
-                                                        * do */
-                                                       break;
-                                               }
-                                       }
+                               seennil |= isnil;
+                               if (seennil && !cmpprv &&
+                                   maxval == NULL && minval == NULL &&
+                                   minbound == NULL && maxbound == NULL) {
+                                       /* we've done all the checking
+                                        * we can do */
+                                       break;
                                }
                                prev = valp;
                        }
@@ -2917,8 +2925,17 @@ BATassertProps(BAT *b)
                                BUN prb;
                                valp = BUNtail(bi, p);
                                bool isnil = cmpf(valp, nilp) == 0;
+                               assert(!isnil || !notnull);
                                assert(b->ttype != TYPE_flt || 
!isinf(*(flt*)valp));
                                assert(b->ttype != TYPE_dbl || 
!isinf(*(dbl*)valp));
+                               if (minbound && !isnil) {
+                                       cmp = cmpf(minbound, valp);
+                                       assert(cmp <= 0);
+                               }
+                               if (maxbound && !isnil) {
+                                       cmp = cmpf(maxbound, valp);
+                                       assert(cmp > 0);
+                               }
                                if (maxval && !isnil) {
                                        cmp = cmpf(maxval, valp);
                                        assert(cmp >= 0);
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -668,6 +668,9 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool 
        oid hseq = n->hseqbase;
        char buf[64];
        lng t0 = 0;
+       ValRecord minprop, maxprop;
+       const void *minbound = NULL, *maxbound = NULL;
+       int (*atomcmp) (const void *, const void *) = ATOMcompare(b->ttype);
 
        if (b == NULL || n == NULL || BATcount(n) == 0) {
                return GDK_SUCCEED;
@@ -696,7 +699,13 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool 
 
        cnt = canditer_init(&ci, n, s);
        if (cnt == 0) {
-               goto doreturn;
+               bat_iterator_end(&ni);
+               TRC_DEBUG(ALGO, "b=%s,n=" ALGOBATFMT ",s=" ALGOOPTBATFMT
+                         " -> " ALGOBATFMT " (" LLFMT " usec)\n",
+                         buf, ALGOBATPAR(n), ALGOOPTBATPAR(s), ALGOBATPAR(b),
+                         GDKusec() - t0);
+
+               return GDK_SUCCEED;
        }
 
        if (BUNlast(b) + cnt > BUN_MAX) {
@@ -723,10 +732,33 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool 
        MT_lock_unset(&n->theaplock);
 
        MT_lock_set(&b->theaplock);
+       const bool notnull = BATgetprop_nolock(b, GDK_NOT_NULL) != NULL;
+       if ((prop = BATgetprop_nolock(b, GDK_MIN_BOUND)) != NULL &&
+           VALcopy(&minprop, prop) != NULL) {
+               minbound = VALptr(&minprop);
+               if (ci.ncand == BATcount(n) &&
+                   npropminval != NULL &&
+                   atomcmp(VALptr(npropminval), minbound) < 0) {
+                       assert(0);
+                       GDKerror("value out of bounds\n");
+                       goto bailout;
+               }
+       }
+       if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL &&
+           VALcopy(&maxprop, prop) != NULL) {
+               maxbound = VALptr(&maxprop);
+               if (ci.ncand == BATcount(n) &&
+                   npropmaxval != NULL &&
+                   atomcmp(VALptr(npropmaxval), maxbound) >= 0) {
+                       assert(0);
+                       GDKerror("value out of bounds\n");
+                       goto bailout;
+               }
+       }
 
        if (BATcount(b) == 0 || (prop = BATgetprop_nolock(b, GDK_MAX_VALUE)) != 
NULL) {
                if (npropmaxval != NULL) {
-                       if (BATcount(b) == 0 || ATOMcmp(b->ttype, VALptr(prop), 
VALptr(npropmaxval)) < 0) {
+                       if (BATcount(b) == 0 || atomcmp(VALptr(prop), 
VALptr(npropmaxval)) < 0) {
                                if (s == NULL) {
                                        BATsetprop_nolock(b, GDK_MAX_VALUE, 
b->ttype, VALptr(npropmaxval));
                                        if (npropmaxpos != NULL)
@@ -745,7 +777,7 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool 
        }
        if (BATcount(b) == 0 || (prop = BATgetprop_nolock(b, GDK_MIN_VALUE)) != 
NULL) {
                if (npropminval != NULL) {
-                       if (BATcount(b) == 0 || ATOMcmp(b->ttype, VALptr(prop), 
VALptr(npropminval)) > 0) {
+                       if (BATcount(b) == 0 || atomcmp(VALptr(prop), 
VALptr(npropminval)) > 0) {
                                if (s == NULL) {
                                        BATsetprop_nolock(b, GDK_MIN_VALUE, 
b->ttype, VALptr(npropminval));
                                        if (npropminpos != NULL)
@@ -779,8 +811,19 @@ BATappend2(BAT *b, BAT *n, BAT *s, bool 
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to