Changeset: f821bf402bf8 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/f821bf402bf8
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
Branch: geo-update
Log Message:
Fixed the st_collect aggregate to also support non-grouped aggregation. Also
changed the module name for the aggregate functions to avoid slicing up the
input.
diffs (189 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -921,10 +921,11 @@ GEOSGeom_getCollectionType (int GEOSGeom
/* Group By operation. Joins geometries together in the same group into a
MultiGeometry */
//TODO Check if the SRID is consistent within a group (right now we only use
the first SRID)
+//TODO The number of candidates is getting wrong here
str
wkbCollectAggrSubGroupedCand(bat *outid, const bat *bid, const bat *gid, const
bat *eid, const bat *sid, const bit *skip_nils)
{
- BAT *b = NULL, *g = NULL, *e = NULL, *s = NULL, *out = NULL;
+ BAT *b = NULL, *g = NULL, *s = NULL, *out = NULL;
BAT *sortedgroups, *sortedorder, *sortedinput;
BATiter bi;
const oid *gids = NULL;
@@ -941,12 +942,14 @@ wkbCollectAggrSubGroupedCand(bat *outid,
wkb **unions = NULL;
GEOSGeom *unionGroup = NULL, collection;
+ //Not using these variables
(void)skip_nils;
(void)eid;
- (void)sid;
-
- //Get the BAT descriptors for the value and group bat
- if ((b = BATdescriptor(*bid)) == NULL || (gid && !is_bat_nil(*gid) &&
(g = BATdescriptor(*gid)) == NULL)) {
+
+ //Get the BAT descriptors for the value, group and candidate bats
+ if ((b = BATdescriptor(*bid)) == NULL ||
+ (gid && !is_bat_nil(*gid) && (g = BATdescriptor(*gid)) == NULL)
||
+ (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) ==
NULL)) {
msg = createException(MAL, "geom.Collect",
RUNTIME_OBJECT_MISSING);
goto free;
}
@@ -955,7 +958,7 @@ wkbCollectAggrSubGroupedCand(bat *outid,
msg = createException(MAL, "geom.Collect", "BAT sort failed.");
goto free;
}
-
+
//Project new order onto input bat IF the sortedorder isn't dense (in
which case, the original input order is correct)
if (!BATtdense(sortedorder)) {
sortedinput = BATproject(sortedorder,b);
@@ -964,6 +967,7 @@ wkbCollectAggrSubGroupedCand(bat *outid,
b = sortedinput;
g = sortedgroups;
BBPunfix(sortedorder->batCacheid);
+
}
else {
BBPunfix(sortedgroups->batCacheid);
@@ -971,17 +975,11 @@ wkbCollectAggrSubGroupedCand(bat *outid,
}
//Fill in the values of the group aggregate operation
- if ((err = BATgroupaggrinit(b, g, e, s, &min, &max, &ngrp, &ci,
&ncand)) != NULL) {
+ if ((err = BATgroupaggrinit(b, g, NULL, s, &min, &max, &ngrp, &ci,
&ncand)) != NULL) {
msg = createException(MAL, "geom.Collect", "%s", err);
goto free;
}
- if (ngrp == 0) {
- msg = createException(MAL, "geom.Collect", "Number of groups is
equal to 0");
- //TODO Return empty BAT?
- goto free;
- }
-
//Create a new BAT column of wkb type, with lenght equal to the number
of groups
if ((out = COLnew(min, ATOMindex("wkb"), ngrp, TRANSIENT)) == NULL) {
msg = createException(MAL, "geom.Collect", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
@@ -1025,7 +1023,7 @@ wkbCollectAggrSubGroupedCand(bat *outid,
//Save collection to unions array as wkb
unions[lastGrp] = geos2wkb(collection);
- //Frees for the previous group
+ //TODO Frees for the previous group (am I
missing the GEOSGeom_destroy call for unionGroup[i])?
GEOSGeom_destroy(collection);
GDKfree(unionGroup);
@@ -1086,12 +1084,16 @@ wkbCollectAggrSubGroupedCand(bat *outid,
BBPunfix(b->batCacheid);
if (g)
BBPunfix(g->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
return MAL_SUCCEED;
free:
if (b)
BBPunfix(b->batCacheid);
if (g)
BBPunfix(g->batCacheid);
+ if (s)
+ BBPunfix(s->batCacheid);
return msg;
}
@@ -1101,10 +1103,60 @@ wkbCollectAggrSubGrouped(bat *out, const
return wkbCollectAggrSubGroupedCand(out, bid, gid, eid, NULL,
skip_nils);
}
-str
-wkbCollectAggrGrouped(bat *out, const bat *bid, const bat *gid, const bat *eid)
-{
- return wkbCollectAggrSubGroupedCand(out, bid, gid, eid, NULL,
&(bit){1});
+//TODO Use this for the grouped version, just need to separate the groups and
then call this one
+str
+wkbCollectAggr (wkb **out, const bat *bid) {
+ str msg = MAL_SUCCEED;
+ BAT *b = NULL;
+ GEOSGeom *unionGroup = NULL, collection;
+ int geomCollectionType = -1;
+
+ if ((b = BATdescriptor(*bid)) == NULL) {
+ msg = createException(MAL, "geom.Collect",
RUNTIME_OBJECT_MISSING);
+ if (b)
+ BBPunfix(b->batCacheid);
+ return msg;
+ }
+
+ BUN count = BATcount(b);
+
+ if ((unionGroup = GDKzalloc(sizeof(GEOSGeom) * count)) == NULL) {
+ msg = createException(MAL, "geom.Collect", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
+ BBPunfix(b->batCacheid);
+ return msg;
+ }
+
+ BATiter bi = bat_iterator(b);
+ for (BUN i = 0; i < count; i++) {
+ oid p = i + b->hseqbase;
+ wkb *inWKB = (wkb *)BUNtvar(bi, p);
+ unionGroup[i] = wkb2geos(inWKB);
+
+ //Set collection type on first geometry
+ if (geomCollectionType == -1)
+ geomCollectionType =
GEOSGeom_getCollectionType(GEOSGeomTypeId(unionGroup[i]));
+ //Then, check if we need to change it a Geometry collection (if
the current geometry is different from the previous type)
+ if (geomCollectionType != GEOS_GEOMETRYCOLLECTION &&
GEOSGeom_getCollectionType(GEOSGeomTypeId(unionGroup[i])) != geomCollectionType)
+ geomCollectionType = GEOS_GEOMETRYCOLLECTION;
+ }
+ collection = GEOSGeom_createCollection(geomCollectionType, unionGroup,
(unsigned int) count);
+ //Result
+ (*out) = geos2wkb(collection);
+ if (*out == NULL)
+ msg = createException(MAL, "geom.ConvexHull", SQLSTATE(38000)
"Geos operation geos2wkb failed");
+
+ //Frees
+ bat_iterator_end(&bi);
+ if (unionGroup) {
+ for (BUN i = 0; i < count; i++)
+ if (unionGroup[i])
+ GEOSGeom_destroy(unionGroup[i]);
+ GDKfree(unionGroup);
+ }
+ //TODO This free is causing issues, is it not necessary?
+ //GEOSGeom_destroy(collection);
+ BBPunfix(b->batCacheid);
+ return msg;
}
/**
@@ -7537,9 +7589,9 @@ static mel_func geom_init_funcs[] = {
command("geom", "IntersectsGeographic", wkbIntersectsGeographic, false,
"Returns true if the geographic Geometries intersect in any point", args(1, 3,
arg("", bit), arg("a", wkb), arg("b", wkb))),
command("geom", "DistanceGeographic", wkbDistanceGeographic, false, "TODO",
args(1, 3, arg("", dbl), arg("a", wkb), arg("b", wkb))),
command("geom", "CoversGeographic", wkbDistanceGeographic, false, "TODO",
args(1, 3, arg("", bit), arg("a", wkb), arg("b", wkb))),
- command("geom", "Collect", wkbCollectAggrGrouped, false, "TODO", args(1, 4,
batarg("", wkb), batarg("val", wkb), batarg("g", oid), batargany("e", 1))),
- command("geom", "subCollect", wkbCollectAggrSubGrouped, false, "TODO",
args(1, 5, batarg("", wkb), batarg("val", wkb), batarg("g", oid), batarg("e",
oid), arg("skip_nils", bit))),
- command("geom", "subCollect", wkbCollectAggrSubGroupedCand, false, "TODO",
args(1, 7, batarg("", wkb), batarg("val", wkb), batarg("g", oid),
batargany("e", 1), batarg("g", oid), arg("skip_nils", bit),
arg("abort_on_error", bit))),
+ command("aggr", "Collect", wkbCollectAggr, false, "TODO", args(1, 2, arg("",
wkb), batarg("val", wkb))),
+ command("aggr", "subCollect", wkbCollectAggrSubGrouped, false, "TODO",
args(1, 5, batarg("", wkb), batarg("val", wkb), batarg("g", oid), batarg("e",
oid), arg("skip_nils", bit))),
+ command("aggr", "subCollect", wkbCollectAggrSubGroupedCand, false, "TODO",
args(1, 6, batarg("", wkb), batarg("val", wkb), batarg("g", oid),
batargany("e", 1), batarg("g", oid), arg("skip_nils", bit))),
command("geom", "hasZ", geoHasZ, false, "returns 1 if the geometry has z
coordinate", args(1,2, arg("",int),arg("flags",int))),
command("geom", "hasM", geoHasM, false, "returns 1 if the geometry has m
coordinate", args(1,2, arg("",int),arg("flags",int))),
diff --git a/geom/monetdb5/geom.h b/geom/monetdb5/geom.h
--- a/geom/monetdb5/geom.h
+++ b/geom/monetdb5/geom.h
@@ -88,8 +88,8 @@ str wkbIntersectsGeographic(bit* out, wk
str wkbCoversGeographic(bit* out, wkb** a, wkb** b);
str wkbCollectAggrSubGroupedCand(bat* outid, const bat* bid, const bat* gid,
const bat* eid, const bat* sid, const bit* skip_nils);
-str wkbCollectAggrSubGrouped(bat* out, const bat* bid, const bat* gid, const
bat* eid, const bit* skip_nils);
-str wkbCollectAggrGrouped(bat* out, const bat* bid, const bat* gid, const bat*
eid);
+str wkbCollectAggrSubGrouped(bat *out, const bat *bid, const bat *gid, const
bat *eid, const bit *skip_nils);
+str wkbCollectAggr (wkb **out, const bat *bid);
/**
*
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list