Changeset: acfef2f8b861 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/acfef2f8b861
Modified Files:
        gdk/gdk_batop.c
Branch: Sep2022
Log Message:

Deal with string offsets pointing outside of vheap.

This could happen if a server is killed after a new value was added to
a string column at a previously (by SQL) deleted location, but before
this update was committed.
This fixes bug #7339.


diffs (71 lines):

diff --git a/gdk/gdk_batop.c b/gdk/gdk_batop.c
--- a/gdk/gdk_batop.c
+++ b/gdk/gdk_batop.c
@@ -1229,9 +1229,13 @@ BATappend_or_update(BAT *b, BAT *p, cons
                                continue;
                        }
 
-                       const void *old = BUNtvar(bi, updid);
+                       /* it is possible that a previous run was killed
+                        * after an update (with a mmapped tail file)
+                        * but before that was committed, then the
+                        * offset may point outside of the vheap */
+                       const void *old = BUNtvaroff(bi, updid) < bi.vhfree ? 
BUNtvar(bi, updid) : NULL;
 
-                       if (atomcmp(old, new) == 0) {
+                       if (old && atomcmp(old, new) == 0) {
                                /* replacing with the same value:
                                 * nothing to do */
                                continue;
@@ -1239,9 +1243,10 @@ BATappend_or_update(BAT *b, BAT *p, cons
 
                        bool isnil = atomcmp(new, nil) == 0;
                        anynil |= isnil;
-                       if (b->tnil &&
-                           !anynil &&
-                           atomcmp(old, nil) == 0) {
+                       if (old == NULL ||
+                           (b->tnil &&
+                            !anynil &&
+                            atomcmp(old, nil) == 0)) {
                                /* if old value is nil and no new
                                 * value is, we're not sure anymore
                                 * about the nil property, so we must
@@ -1256,8 +1261,9 @@ BATappend_or_update(BAT *b, BAT *p, cons
                                        /* new value is larger than
                                         * previous largest */
                                        bi.maxpos = updid;
-                               } else if (atomcmp(BUNtvar(bi, bi.maxpos), old) 
== 0 &&
-                                          atomcmp(new, old) != 0) {
+                               } else if (old == NULL ||
+                                          (atomcmp(BUNtvar(bi, bi.maxpos), 
old) == 0 &&
+                                           atomcmp(new, old) != 0)) {
                                        /* old value is equal to
                                         * largest and new value is
                                         * smaller, so we don't know
@@ -1272,8 +1278,9 @@ BATappend_or_update(BAT *b, BAT *p, cons
                                        /* new value is smaller than
                                         * previous smallest */
                                        bi.minpos = updid;
-                               } else if (atomcmp(BUNtvar(bi, bi.minpos), old) 
== 0 &&
-                                          atomcmp(new, old) != 0) {
+                               } else if (old == NULL ||
+                                          (atomcmp(BUNtvar(bi, bi.minpos), 
old) == 0 &&
+                                           atomcmp(new, old) != 0)) {
                                        /* old value is equal to
                                         * smallest and new value is
                                         * larger, so we don't know
@@ -1286,7 +1293,12 @@ BATappend_or_update(BAT *b, BAT *p, cons
                                MT_rwlock_wrlock(&b->thashlock);
                                locked = true;
                        }
-                       HASHdelete_locked(&bi, updid, old);
+                       if (old)
+                               HASHdelete_locked(&bi, updid, old);
+                       else if (b->thash) {
+                               doHASHdestroy(b, b->thash);
+                               b->thash = NULL;
+                       }
 
                        var_t d;
                        switch (b->twidth) {
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to