Changeset: c38b49e1fc9e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c38b49e1fc9e
Modified Files:
        clients/mapilib/msettings_internal.h
        gdk/gdk_bat.c
        gdk/gdk_batop.c
        monetdb5/mal/Tests/tst025.maltest
Branch: Mar2025
Log Message:

Coverity-inspired fixes.
BUNdelete is now only allowed to delete the last value from a bat.


diffs (229 lines):

diff --git a/clients/mapilib/msettings_internal.h 
b/clients/mapilib/msettings_internal.h
--- a/clients/mapilib/msettings_internal.h
+++ b/clients/mapilib/msettings_internal.h
@@ -88,6 +88,8 @@ realloc_with_fallback(msettings_allocato
 {
        return alloc
                ? alloc(alloc_state, old, size)
+               : size == 0
+               ? (free(old), NULL)
                : realloc(old, size);
 }
 
@@ -114,8 +116,11 @@ msettings_alloc_zeroed(const msettings *
 static inline void*
 msettings_dealloc(const msettings *mp, void *data)
 {
-       if (data != NULL)
-               msettings_realloc(mp, data, 0);
+       if (data != NULL) {
+               void *p = msettings_realloc(mp, data, 0);
+               (void) p;       /* in case we don't have asserts */
+               assert(p == NULL);
+       }
        return NULL;
 }
 
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -369,7 +369,9 @@ BATextend(BAT *b, BUN newcap)
         * otherwise you may easily corrupt the administration of
         * malloc.
         */
+       MT_lock_set(&b->theaplock);
        if (newcap <= BATcapacity(b)) {
+               MT_lock_unset(&b->theaplock);
                return GDK_SUCCEED;
        }
 
@@ -380,7 +382,6 @@ BATextend(BAT *b, BUN newcap)
                theap_size = (size_t) newcap << b->tshift;
        }
 
-       MT_lock_set(&b->theaplock);
        if (b->theap->base) {
                TRC_DEBUG(HEAP, "HEAPgrow in BATextend %s %zu %zu\n",
                          b->theap->filename, b->theap->size, theap_size);
@@ -925,6 +926,7 @@ BUNappendmulti(BAT *b, const void *value
                }
                if (dense) {
                        MT_lock_set(&b->theaplock);
+                       assert(BATtdense(b)); /* no change (coverity) */
                        if (b->batCount == 0)
                                b->tseqbase = ovals ? ovals[0] : oid_nil;
                        BATsetcount(b, BATcount(b) + count);
@@ -1287,74 +1289,45 @@ BUNappend(BAT *b, const void *t, bool fo
 gdk_return
 BUNdelete(BAT *b, oid o)
 {
-       BUN p;
-       BATiter bi = bat_iterator_nolock(b);
-       const void *val;
-       bool locked = false;
-       BUN nunique;
+       BATiter bi = bat_iterator(b);
 
-       assert(!is_oid_nil(b->hseqbase) || BATcount(b) == 0);
-       if (o < b->hseqbase || o >= b->hseqbase + BATcount(b)) {
-               /* value already not there */
-               return GDK_SUCCEED;
+       if (bi.count == 0) {
+               bat_iterator_end(&bi);
+               GDKerror("cannot delete from empty bat\n");
+               return GDK_FAIL;
+       }
+       if (is_oid_nil(b->hseqbase)) {
+               bat_iterator_end(&bi);
+               GDKerror("cannot delete from bat with VOID hseqbase\n");
+               return GDK_FAIL;
        }
-       assert(BATcount(b) > 0); /* follows from "if" above */
-       p = o - b->hseqbase;
-       if (p < b->batInserted) {
+
+       BUN p = o - b->hseqbase;
+
+       if (bi.count - 1 != p) {
+               bat_iterator_end(&bi);
+               GDKerror("cannot delete anything other than last value\n");
+               return GDK_FAIL;
+       }
+       if (b->batInserted >= bi.count) {
+               bat_iterator_end(&bi);
                GDKerror("cannot delete committed value\n");
                return GDK_FAIL;
        }
+
        TRC_DEBUG(ALGO, ALGOBATFMT " deleting oid " OIDFMT "\n", ALGOBATPAR(b), 
o);
        /* load hash so that we can maintain it */
        (void) BATcheckhash(b);
 
-       val = BUNtail(bi, p);
-       /* writing the values should be locked, reading could be done
-        * unlocked (since we're the only thread that should be changing
-        * anything) */
+       BUN nunique = HASHdelete(&bi, p, BUNtail(bi, p));
+       ATOMdel(b->ttype, b->tvheap, (var_t *) BUNtloc(bi, p));
+       bat_iterator_end(&bi);
+
        MT_lock_set(&b->theaplock);
        if (b->tmaxpos == p)
                b->tmaxpos = BUN_NONE;
        if (b->tminpos == p)
                b->tminpos = BUN_NONE;
-       MT_lock_unset(&b->theaplock);
-       nunique = HASHdelete(&bi, p, val);
-       ATOMdel(b->ttype, b->tvheap, (var_t *) BUNtloc(bi, p));
-       if (p != BATcount(b) - 1 &&
-           (b->ttype != TYPE_void || BATtdense(b))) {
-               /* replace to-be-delete BUN with last BUN; materialize
-                * void column before doing so */
-               if (b->ttype == TYPE_void &&
-                   BATmaterialize(b, BUN_NONE) != GDK_SUCCEED)
-                       return GDK_FAIL;
-               if (ATOMstorage(b->ttype) == TYPE_msk) {
-                       msk mval = mskGetVal(b, BATcount(b) - 1);
-                       assert(b->thash == NULL);
-                       mskSetVal(b, p, mval);
-                       /* don't leave garbage */
-                       mskClr(b, BATcount(b) - 1);
-               } else {
-                       val = Tloc(b, BATcount(b) - 1);
-                       nunique = HASHdelete(&bi, BATcount(b) - 1, val);
-                       memcpy(Tloc(b, p), val, b->twidth);
-                       nunique = HASHinsert(&bi, p, val);
-                       MT_lock_set(&b->theaplock);
-                       locked = true;
-                       if (b->tminpos == BATcount(b) - 1)
-                               b->tminpos = p;
-                       if (b->tmaxpos == BATcount(b) - 1)
-                               b->tmaxpos = p;
-               }
-               /* no longer sorted */
-               if (!locked) {
-                       MT_lock_set(&b->theaplock);
-                       locked = true;
-               }
-               b->tsorted = b->trevsorted = false;
-               b->theap->dirty = true;
-       }
-       if (!locked)
-               MT_lock_set(&b->theaplock);
        if (b->tnosorted >= p)
                b->tnosorted = 0;
        if (b->tnorevsorted >= p)
@@ -1376,6 +1349,9 @@ BUNdelete(BAT *b, oid o)
        }
        MT_lock_unset(&b->theaplock);
        OIDXdestroy(b);
+       STRMPdestroy(b);
+       RTREEdestroy(b);
+       PROPdestroy(b);
        return GDK_SUCCEED;
 }
 
diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -356,23 +356,24 @@ append_varsized_bat(BAT *b, BATiter *ni,
                if (BATextend(b, grows) != GDK_SUCCEED)
                        return GDK_FAIL;
        }
-       if (mayshare &&
-           BATcount(b) == 0 &&
-           b->batRole == TRANSIENT &&
-           ni->restricted == BAT_READ &&
-           b->tvheap != ni->vh) {
-               /* if b is still empty, in the transient farm, and n
-                * is read-only, we replace b's vheap with a reference
-                * to n's */
+       if (mayshare) {
                MT_lock_set(&b->theaplock);
-               bat bid = b->tvheap->parentid;
-               HEAPdecref(b->tvheap, true);
-               HEAPincref(ni->vh);
-               b->tvheap = ni->vh;
+               if (BATcount(b) == 0 &&
+                   b->batRole == TRANSIENT &&
+                   ni->restricted == BAT_READ &&
+                   b->tvheap != ni->vh) {
+                       /* if b is still empty, in the transient farm,
+                        * and n is read-only, we replace b's vheap with
+                        * a reference to n's */
+                       bat bid = b->tvheap->parentid;
+                       HEAPdecref(b->tvheap, true);
+                       HEAPincref(ni->vh);
+                       b->tvheap = ni->vh;
+                       BBPretain(ni->vh->parentid);
+                       if (bid != b->batCacheid)
+                               BBPrelease(bid);
+               }
                MT_lock_unset(&b->theaplock);
-               BBPretain(ni->vh->parentid);
-               if (bid != b->batCacheid)
-                       BBPrelease(bid);
        }
        if (b->tvheap == ni->vh) {
                /* if b and n use the same vheap, we only need to copy
diff --git a/monetdb5/mal/Tests/tst025.maltest 
b/monetdb5/mal/Tests/tst025.maltest
--- a/monetdb5/mal/Tests/tst025.maltest
+++ b/monetdb5/mal/Tests/tst025.maltest
@@ -20,7 +20,7 @@ 5442033
 2
 5645862
 
-statement ok
+statement error
 bat.delete(b,1@0)
 
 query II rowsort
@@ -29,6 +29,8 @@ io.print(b)
 0
 5140046
 1
+5442033
+2
 5645862
 
 statement ok
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to