Changeset: ea29cca40671 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/ea29cca40671
Modified Files:
        gdk/gdk.h
        gdk/gdk_bat.c
Branch: Jul2021
Log Message:

Deal with offsets that point outside of the vheap.
This is for the logger's sake during application of the WAL.


diffs (166 lines):

diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -994,6 +994,8 @@ bat_iterator_nolock(BAT *b)
                        .shift = b->tshift,
                        .type = b->ttype,
                        .tseq = b->tseqbase,
+                       .hfree = b->theap->free,
+                       .vhfree = b->tvheap ? b->tvheap->free : 0,
 #ifndef NDEBUG
                        .locked = false,
 #endif
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1333,68 +1333,102 @@ BUNinplacemulti(BAT *b, const oid *posit
                        ((const void **) values)[i] :
                        (const void *) ((const char *) values + (i << 
b->tshift));
 
-               val = BUNtail(bi, p);   /* old value */
-               if (ATOMcmp(b->ttype, 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) {
-                       /* if old value is nil and new value isn't, we're not
-                        * sure anymore about the nil property, so we must
-                        * clear it */
-                       b->tnil = false;
+               /* retrieve old value, but if this comes from the
+                * logger, we need to deal with offsets that point
+                * outside of the valid vheap */
+               if (b->tvarsized) {
+                       if (b->ttype) {
+                               size_t off = BUNtvaroff(bi, p);
+                               if (off < bi.vhfree)
+                                       val = bi.vh->base + off;
+                               else
+                                       val = NULL; /* bad offset */
+                       } else {
+                               val = BUNtpos(bi, p);
+                       }
+               } else {
+                       val = BUNtloc(bi, p);
                }
-               if (b->ttype != TYPE_void && ATOMlinear(b->ttype)) {
-                       const ValRecord *prop;
 
-                       MT_lock_set(&b->theaplock);
-                       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) {
-                                       /* 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) {
-                                       /* old value is equal to largest and
-                                        * new value is smaller (see above),
-                                        * so we don't know anymore which is
-                                        * the largest */
-                                       BATrmprop_nolock(b, GDK_MAX_VALUE);
+               if (val) {
+                       if (ATOMcmp(b->ttype, 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) {
+                               /* if old value is nil and new value
+                                * isn't, we're not sure anymore about
+                                * the nil property, so we must clear
+                                * it */
+                               b->tnil = false;
+                       }
+                       if (b->ttype != TYPE_void && ATOMlinear(b->ttype)) {
+                               const ValRecord *prop;
+
+                               MT_lock_set(&b->theaplock);
+                               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) {
+                                               /* 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) {
+                                               /* old value is equal to
+                                                * largest and new value
+                                                * is smaller (see
+                                                * above), so we don't
+                                                * know anymore which is
+                                                * the largest */
+                                               BATrmprop_nolock(b, 
GDK_MAX_VALUE);
+                                               BATrmprop_nolock(b, 
GDK_MAX_POS);
+                                       }
+                               } else {
                                        BATrmprop_nolock(b, GDK_MAX_POS);
                                }
-                       } else {
-                               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) {
-                                       /* 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) {
-                                       /* old value is equal to smallest and
-                                        * new value is larger (see above), so
-                                        * we don't know anymore which is the
-                                        * smallest */
-                                       BATrmprop_nolock(b, GDK_MIN_VALUE);
+                               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) {
+                                               /* 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) {
+                                               /* old value is equal to
+                                                * smallest and new
+                                                * value is larger (see
+                                                * above), so we don't
+                                                * know anymore which is
+                                                * the smallest */
+                                               BATrmprop_nolock(b, 
GDK_MIN_VALUE);
+                                               BATrmprop_nolock(b, 
GDK_MIN_POS);
+                                       }
+                               } else {
                                        BATrmprop_nolock(b, GDK_MIN_POS);
                                }
+                               BATrmprop_nolock(b, GDK_UNIQUE_ESTIMATE);
+                               MT_lock_unset(&b->theaplock);
                        } else {
-                               BATrmprop_nolock(b, GDK_MIN_POS);
+                               PROPdestroy(b);
                        }
-                       BATrmprop_nolock(b, GDK_UNIQUE_ESTIMATE);
-                       MT_lock_unset(&b->theaplock);
+                       HASHdelete_locked(b, p, val);   /* first delete old 
value from hash */
                } else {
+                       /* out of range old value, so the properties and
+                        * hash cannot be trusted */
                        PROPdestroy(b);
+                       Hash *hs = b->thash;
+                       if (hs) {
+                               b->thash = NULL;
+                               doHASHdestroy(b, hs);
+                       }
                }
                OIDXdestroy(b);
                IMPSdestroy(b);
 
-               HASHdelete_locked(b, p, val);   /* first delete old value from 
hash */
                if (b->tvarsized && b->ttype) {
                        var_t _d;
                        ptr _ptr;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to