Changeset: 21ca449af480 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=21ca449af480
Modified Files:
monetdb5/modules/mal/array.mx
Branch: SciQL-2
Log Message:
ARRAYtiles*(): more informative error messages and extra consistency checks
If the dimensions do not comply with (at least) these checks / properties,
(our current implementation of) tiled array aggregation
does not make much sense.
In fact, more exhaustive (expensive) checks would be required
to ensure that all dimensions are fully (sub-)sorted,
as our current implementation (silently) assumes.
diffs (130 lines):
diff --git a/monetdb5/modules/mal/array.mx b/monetdb5/modules/mal/array.mx
--- a/monetdb5/modules/mal/array.mx
+++ b/monetdb5/modules/mal/array.mx
@@ -567,7 +567,7 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
@1 *bValT = NULL;
@3 *bResT = NULL;
@8 **bDimsT = NULL, **bOffsetsT = NULL, *dMin = NULL, *dMax = NULL;
- BUN p, r, arrcnt = 0, offcnt = 0;
+ BUN p, r, arrsze = 0, arrcnt = 0, offcnt = 0;
int *dSize = NULL;
oid arrbase = 0, offbase = 0;
@@ -593,6 +593,7 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
AGGR_CLEANUP();
throw(MAL, "array.@4", RUNTIME_OBJECT_MISSING);
}
+ arrsze = 1;
for (i = 0; i < ndims; i++) {
bDims[i] = BATdescriptor(*(int*)getArgReference(stk,pci,2+i*3));
bOffsets[i] =
BATdescriptor(*(int*)getArgReference(stk,pci,2+i*3+1));
@@ -601,6 +602,11 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
throw(MAL, "array.@4", RUNTIME_OBJECT_MISSING);
}
dSize[i] = *(int*)getArgReference(stk,pci,2+i*3+2);
+ if (dSize[i] == 0) {
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "size dimension %d must not be
0", i);
+ }
+ arrsze *= dSize[i];
}
/* type check the shapes, prepare iterators, and compute the min/max of
the dimensions */
if (!BAThdense(bVal)) {
@@ -612,32 +618,75 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
throw(MAL, "array.@4", "tail of value BAT must be of type @1");
}
arrcnt = BATcount(bVal);
+ if (arrcnt != arrsze) {
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "count of value BAT ("BUNFMT") !=
product of dimension sizes ("BUNFMT")",
+ arrcnt, arrsze);
+ }
arrbase = bVal->hseqbase;
offbase = bOffsets[0]->hseqbase;
offcnt = BATcount(bOffsets[0]);
for (i = 0; i < ndims; i++) {
if (!BAThdense(bDims[i])) {
AGGR_CLEANUP();
- throw(MAL, "array.@4", "head of all dimension BATs must
be dense");
+ throw(MAL, "array.@4", "head of dimension BAT %d is not
dense", i);
}
if (!BAThdense(bOffsets[i])) {
AGGR_CLEANUP();
- throw(MAL, "array.@4", "head of all offset BATs must be
dense");
+ throw(MAL, "array.@4", "head of offset BAT %d is not
dense", i);
}
if (bDims[i]->hseqbase != arrbase || BATcount(bDims[i]) !=
arrcnt) {
AGGR_CLEANUP();
- throw(MAL, "array.@4", "head of all dimension BATs must
be aligned with head of value BAT");
+ throw(MAL, "array.@4", "head of dimension BAT %d is not
aligned with head of value BAT", i);
}
if (bOffsets[i]->hseqbase != offbase || BATcount(bOffsets[i])
!= offcnt) {
AGGR_CLEANUP();
- throw(MAL, "array.@4", "heads of all offset BATs must
be aligned");
+ throw(MAL, "array.@4", "head of offset BAT %d is not
aligned with head of offset BAT 0", i);
}
if (bDims[i]->ttype != TYPE_@8 || bDims[i]->ttype !=
bOffsets[i]->ttype) {
AGGR_CLEANUP();
- throw(MAL, "array.@4", SEMANTIC_TYPE_MISMATCH);
+ throw(MAL, "array.@4", "tail type of dimension BAT %d
is not type @8", i);
}
+ /* ! might require 2 full scans ! */
BATmin(bDims[i], &(dMin[i]));
BATmax(bDims[i], &(dMax[i]));
+ if ((int) (dMax[i] - dMin[i] + 1) != dSize[i]) {
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "range of dimension BAT %d (%d)
does not match its size (%d)",
+ i, (int) (dMax[i] - dMin[i] + 1), dSize[i]);
+ }
+
+ /* might require (partial) scans; hence, only done when
+ * assertions or property checking enabled */
+#ifdef NDEBUG
+ PROPDEBUG
+#endif
+ {
+ BAT *slice;
+ slice = BATslice(bDims[i],0,arrsze);
+ BATderiveHeadProps(BATmirror(slice),0);
+ if (!BATtordered(slice)) {
+ BBPunfix(slice->batCacheid);
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "values of dimension %d
are not sorted %s",
+ i, i ? "within first value of
preceeding dimension" : "");
+ }
+ BBPunfix(slice->batCacheid);
+ if (arrsze < arrcnt) {
+ slice = BATslice(bDims[i],arrcnt-arrsze,arrcnt);
+ BATderiveHeadProps(BATmirror(slice),0);
+ if (!BATtordered(slice)) {
+ BBPunfix(slice->batCacheid);
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "values of
dimension %d are not sorted %s",
+ i, i ? "within last value of
preceeding dimension" : "");
+ }
+ BBPunfix(slice->batCacheid);
+ }
+ }
+
+ arrsze /= dSize[i];
+ assert(arrsze);
}
/* access tails as arrays */
@@ -645,6 +694,16 @@ ARRAYtiles_@4_@1_@8(Client cntxt, MalBlk
for (i = 0; i < ndims; i++) {
bDimsT[i] = (@8*) Tloc(bDims[i], BUNfirst(bDims[i]));
bOffsetsT[i] = (@8*) Tloc(bOffsets[i], BUNfirst(bOffsets[i]));
+ if (bDimsT[i][0] != dMin[i]) {
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "first value of dimension %d
(%d) is not its minimum (%d)",
+ i, (int) bDimsT[i][0], (int) dMin[i]);
+ }
+ if (bDimsT[i][arrcnt-1] != dMax[i]) {
+ AGGR_CLEANUP();
+ throw(MAL, "array.@4", "last value of dimension %d (%d)
is not its maximum (%d)",
+ i, (int) bDimsT[i][arrcnt-1], (int) dMax[i]);
+ }
}
/* For each anchor piont, compute all cells belong to this tile
(bVal.head
_______________________________________________
checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list