Changeset: 82757727381a for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/82757727381a
Modified Files:
clients/Tests/MAL-signatures.stable.out.int128
clients/Tests/exports.stable.out
gdk/gdk.h
gdk/gdk_aggr.c
gdk/gdk_bat.c
gdk/gdk_batop.c
gdk/gdk_private.h
gdk/gdk_select.c
sql/backends/monet5/sql_cat.c
sql/server/rel_optimizer.c
sql/server/rel_prop.c
sql/server/rel_prop.h
sql/server/sql_mvc.c
sql/server/sql_partition.c
sql/server/sql_partition.h
sql/storage/bat/bat_storage.c
sql/storage/sql_storage.h
sql/storage/store.c
sql/test/merge-partitions/Tests/mergepart01.test
sql/test/merge-partitions/Tests/mergepart30.test
sql/test/merge-partitions/Tests/mergepart31.test
sql/test/merge-partitions/Tests/mergepart32.test
Branch: use_min_max_prop
Log Message:
use min/max bounds and NOT_NULL property on bats under range partitions
diffs (truncated from 1183 to 300 lines):
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
@@ -1,6 +1,3 @@
-stdout of test 'MAL-signatures` in directory 'clients` itself:
-
-#select * from sys.malfunctions() order by module, "function", address,
signature, comment;
% .%1, .%1, .%1, .%1, .%1 # table_name
% module, function, signature, address, comment # name
% clob, clob, clob, clob, clob # type
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
@@ -123,6 +123,7 @@ void BATfakeCommit(BAT *b);
gdk_return BATfirstn(BAT **topn, BAT **gids, BAT *b, BAT *cands, BAT *grps,
BUN n, bool asc, bool nilslast, bool distinct)
__attribute__((__warn_unused_result__));
restrict_t BATgetaccess(BAT *b);
ValPtr BATgetprop(BAT *b, enum prop_t idx);
+ValPtr BATgetprop_nolock(BAT *b, enum prop_t idx);
gdk_return BATgroup(BAT **groups, BAT **extents, BAT **histo, BAT *b, BAT *s,
BAT *g, BAT *e, BAT *h) __attribute__((__warn_unused_result__));
const char *BATgroupaggrinit(BAT *b, BAT *g, BAT *e, BAT *s, oid *minp, oid
*maxp, BUN *ngrpp, struct canditer *ci, BUN *ncand);
gdk_return BATgroupavg(BAT **bnp, BAT **cntsp, BAT *b, BAT *g, BAT *e, BAT *s,
int tp, bool skip_nils, bool abort_on_error, int scale);
@@ -181,6 +182,8 @@ BAT *BATprojectchain(BAT **bats);
gdk_return BATrangejoin(BAT **r1p, BAT **r2p, BAT *l, BAT *rl, BAT *rh, BAT
*sl, BAT *sr, bool li, bool hi, bool anti, bool symmetric, BUN estimate)
__attribute__((__warn_unused_result__));
gdk_return BATreplace(BAT *b, BAT *p, BAT *n, bool force)
__attribute__((__warn_unused_result__));
gdk_return BATreplacepos(BAT *b, const oid *positions, BAT *n, bool autoincr,
bool force) __attribute__((__warn_unused_result__));
+void BATrmprop(BAT *b, enum prop_t idx);
+void BATrmprop_nolock(BAT *b, enum prop_t idx);
gdk_return BATroles(BAT *b, const char *tnme);
BAT *BATsample(BAT *b, BUN n);
BAT *BATsample_with_seed(BAT *b, BUN n, uint64_t seed);
@@ -190,6 +193,8 @@ gdk_return BATsemijoin(BAT **r1p, BAT **
BAT *BATsetaccess(BAT *b, restrict_t mode)
__attribute__((__warn_unused_result__));
void BATsetcapacity(BAT *b, BUN cnt);
void BATsetcount(BAT *b, BUN cnt);
+ValPtr BATsetprop(BAT *b, enum prop_t idx, int type, const void *v);
+ValPtr BATsetprop_nolock(BAT *b, enum prop_t idx, int type, const void *v);
BAT *BATslice(BAT *b, BUN low, BUN high);
gdk_return BATsort(BAT **sorted, BAT **order, BAT **groups, BAT *b, BAT *o,
BAT *g, bool reverse, bool nilslast, bool stable)
__attribute__((__warn_unused_result__));
gdk_return BATstr_group_concat(ValPtr res, BAT *b, BAT *s, BAT *sep, bool
skip_nils, bool abort_on_error, bool nil_if_empty, const char *restrict
separator);
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2234,9 +2234,17 @@ enum prop_t {
GDK_HASH_BUCKETS, /* last used hash bucket size (oid) */
GDK_NUNIQUE, /* number of unique values (oid) */
GDK_UNIQUE_ESTIMATE, /* estimate of number of distinct values (dbl)
*/
+ GDK_MIN_BOUND, /* MINimum allowed value for range partitions
[min, max> */
+ GDK_MAX_BOUND, /* MAXimum of the range partitions [min, max>,
ie. excluding this max value */
+ GDK_NOT_NULL, /* bat bound to be not null */
};
gdk_export ValPtr BATgetprop(BAT *b, enum prop_t idx);
+gdk_export ValPtr BATgetprop_nolock(BAT *b, enum prop_t idx);
+gdk_export ValPtr BATsetprop(BAT *b, enum prop_t idx, int type, const void *v);
+gdk_export ValPtr BATsetprop_nolock(BAT *b, enum prop_t idx, int type, const
void *v);
+gdk_export void BATrmprop(BAT *b, enum prop_t idx);
+gdk_export void BATrmprop_nolock(BAT *b, enum prop_t idx);
/*
* @- BAT relational operators
diff --git a/gdk/gdk_aggr.c b/gdk/gdk_aggr.c
--- a/gdk/gdk_aggr.c
+++ b/gdk/gdk_aggr.c
@@ -84,11 +84,14 @@ BATgroupaggrinit(BAT *b, BAT *g, BAT *e,
/* we need to find out the min and max of g */
const ValRecord *prop;
- prop = BATgetprop(g, GDK_MAX_VALUE);
- if (prop) {
+ if ((prop = BATgetprop(g, GDK_MAX_VALUE)) != NULL) {
assert(prop->vtype == TYPE_oid);
min = 0; /* just assume it starts at 0 */
max = prop->val.oval;
+ } else if ((prop = BATgetprop(g, GDK_MAX_BOUND)) != NULL) {
+ assert(prop->vtype == TYPE_oid);
+ min = 0; /* just assume it starts at 0 */
+ max = prop->val.oval - 1; /* bound is exclusive */
} else {
min = oid_nil; /* note that oid_nil > 0! (unsigned) */
max = 0;
diff --git a/gdk/gdk_bat.c b/gdk/gdk_bat.c
--- a/gdk/gdk_bat.c
+++ b/gdk/gdk_bat.c
@@ -1197,6 +1197,14 @@ BUNappendmulti(BAT *b, const void *value
prop = BATgetprop_nolock(b, GDK_MAX_POS);
BUN maxpos = prop ? (BUN) prop->val.oval : BUN_NONE;
BATiter bi = bat_iterator_nolock(b);
+ ValRecord minprop, maxprop;
+ const void *minbound = NULL, *maxbound = NULL;
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_BOUND)) != NULL &&
+ VALcopy(&minprop, prop) != NULL)
+ minbound = VALptr(&minprop);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL &&
+ VALcopy(&maxprop, prop) != NULL)
+ maxbound = VALptr(&maxprop);
MT_lock_unset(&b->theaplock);
const void *minvalp = NULL, *maxvalp = NULL;
if (minpos != BUN_NONE)
@@ -1206,10 +1214,27 @@ BUNappendmulti(BAT *b, const void *value
if (b->tvarsized) {
const void *vbase = b->tvheap->base;
for (BUN i = 0; i < count; i++) {
+ gdk_return rc;
t = ((void **) values)[i];
- gdk_return rc = tfastins_nocheckVAR(b, p, t);
+ if (minbound &&
+ ATOMcmp(b->ttype, t, minbound) < 0) {
+ assert(0);
+ GDKerror("value not within bounds\n");
+ rc = GDK_FAIL;
+ } else if (maxbound &&
+ ATOMcmp(b->ttype, t, maxbound) >= 0)
{
+ assert(0);
+ GDKerror("value not within bounds\n");
+ rc = GDK_FAIL;
+ } else {
+ rc = tfastins_nocheckVAR(b, p, t);
+ }
if (rc != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
+ if (minbound)
+ VALclear(&minprop);
+ if (maxbound)
+ VALclear(&maxprop);
return rc;
}
if (vbase != b->tvheap->base) {
@@ -1266,6 +1291,10 @@ BUNappendmulti(BAT *b, const void *value
gdk_return rc = tfastins_nocheckFIX(b, p, t);
if (rc != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
+ if (minbound)
+ VALclear(&minprop);
+ if (maxbound)
+ VALclear(&maxprop);
return rc;
}
if (b->thash) {
@@ -1307,6 +1336,10 @@ BUNappendmulti(BAT *b, const void *value
BATsetprop_nolock(b, GDK_MAX_VALUE, b->ttype, maxvalp);
}
MT_lock_unset(&b->theaplock);
+ if (minbound)
+ VALclear(&minprop);
+ if (maxbound)
+ VALclear(&maxprop);
} else {
for (BUN i = 0; i < count; i++) {
gdk_return rc = tfastins_nocheck(b, p, t);
@@ -1462,6 +1495,17 @@ BUNinplacemulti(BAT *b, const oid *posit
BATgetId(b));
return GDK_FAIL;
}
+ MT_lock_set(&b->theaplock);
+ const ValRecord *prop;
+ ValRecord minprop, maxprop;
+ const void *minbound = NULL, *maxbound = NULL;
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_BOUND)) != NULL &&
+ VALcopy(&minprop, prop) != NULL)
+ minbound = VALptr(&minprop);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL &&
+ VALcopy(&maxprop, prop) != NULL)
+ maxbound = VALptr(&maxprop);
+ MT_lock_unset(&b->theaplock);
MT_rwlock_wrlock(&b->thashlock);
for (BUN i = 0; i < count; i++) {
BUN p = autoincr ? positions[0] - b->hseqbase + i :
positions[i] - b->hseqbase;
@@ -1469,6 +1513,15 @@ 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)) {
+ assert(0);
+ GDKerror("value not within bounds\n");
+ MT_rwlock_wrunlock(&b->thashlock);
+ goto bailout;
+ }
/* retrieve old value, but if this comes from the
* logger, we need to deal with offsets that point
* outside of the valid vheap */
@@ -1604,14 +1657,14 @@ BUNinplacemulti(BAT *b, const oid *posit
}
if (ATOMreplaceVAR(b, &_d, t) != GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
- return GDK_FAIL;
+ goto bailout;
}
if (b->twidth < SIZEOF_VAR_T &&
(b->twidth <= 2 ? _d - GDK_VAROFFSET : _d) >=
((size_t) 1 << (8 << b->tshift))) {
/* doesn't fit in current heap, upgrade it */
if (GDKupgradevarheap(b, _d, 0, bi.count) !=
GDK_SUCCEED) {
MT_rwlock_wrunlock(&b->thashlock);
- return GDK_FAIL;
+ goto bailout;
}
}
/* reinitialize iterator after possible heap upgrade */
@@ -1640,7 +1693,7 @@ BUNinplacemulti(BAT *b, const oid *posit
if (ATOMfix(b->ttype, t) != GDK_SUCCEED ||
ATOMunfix(b->ttype, BUNtloc(bi, p)) != GDK_SUCCEED)
{
MT_rwlock_wrunlock(&b->thashlock);
- return GDK_FAIL;
+ goto bailout;
}
switch (ATOMsize(b->ttype)) {
case 0: /* void */
@@ -1721,6 +1774,10 @@ BUNinplacemulti(BAT *b, const oid *posit
MT_lock_unset(&b->theaplock);
}
MT_rwlock_wrunlock(&b->thashlock);
+ if (minbound)
+ VALclear(&minprop);
+ if (maxbound)
+ VALclear(&maxprop);
MT_lock_set(&b->theaplock);
b->theap->dirty = true;
if (b->tvheap)
@@ -1728,6 +1785,13 @@ BUNinplacemulti(BAT *b, const oid *posit
MT_lock_unset(&b->theaplock);
return GDK_SUCCEED;
+
+ bailout:
+ if (minbound)
+ VALclear(&minprop);
+ if (maxbound)
+ VALclear(&maxprop);
+ return GDK_FAIL;
}
/* Replace multiple values given by their positions with the given values. */
@@ -2721,6 +2785,8 @@ BATassertProps(BAT *b)
const ValRecord *prop;
const void *maxval = NULL;
const void *minval = NULL;
+ const void *maxbound = NULL;
+ const void *minbound = NULL;
bool seenmax = false, seenmin = false;
bool seennil = false;
@@ -2728,6 +2794,10 @@ BATassertProps(BAT *b)
maxval = VALptr(prop);
if ((prop = BATgetprop_nolock(b, GDK_MIN_VALUE)) != NULL)
minval = VALptr(prop);
+ if ((prop = BATgetprop_nolock(b, GDK_MAX_BOUND)) != NULL)
+ maxbound = VALptr(prop);
+ if ((prop = BATgetprop_nolock(b, GDK_MIN_BOUND)) != NULL)
+ minbound = VALptr(prop);
if ((prop = BATgetprop_nolock(b, GDK_MAX_POS)) != NULL) {
if (maxval) {
assert(prop->vtype == TYPE_oid);
@@ -2760,6 +2830,14 @@ BATassertProps(BAT *b)
bool isnil = cmpf(valp, nilp) == 0;
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
@@ -2841,6 +2841,7 @@ PROPdestroy_nolock(BAT *b)
PROPrec *p = b->tprops;
PROPrec *n;
+ fprintf(stderr, "#%s "ALGOOPTBATFMT"\n", __func__, ALGOOPTBATPAR(b));
b->tprops = NULL;
while (p) {
n = p->next;
@@ -2882,6 +2883,7 @@ BATrmprop_nolock(BAT *b, enum prop_t idx
{
PROPrec *prop = b->tprops, *prev = NULL;
+ fprintf(stderr, "#%s %d "ALGOOPTBATFMT"\n", __func__, (int) idx,
ALGOOPTBATPAR(b));
while (prop) {
if (prop->id == idx) {
if (prev)
@@ -2902,6 +2904,7 @@ BATsetprop_nolock(BAT *b, enum prop_t id
{
PROPrec *p;
+ fprintf(stderr, "#%s %d "ALGOOPTBATFMT"\n", __func__, (int) idx,
ALGOOPTBATPAR(b));
p = b->tprops;
while (p && p->id != idx)
p = p->next;
diff --git a/gdk/gdk_private.h b/gdk/gdk_private.h
--- a/gdk/gdk_private.h
+++ b/gdk/gdk_private.h
@@ -28,6 +28,15 @@ enum heaptype {
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]