Changeset: 491621f08c76 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=491621f08c76
Modified Files:
geom/monetdb5/geom.c
geom/monetdb5/geom.h
geom/monetdb5/geom.mal
geom/sql/40_geom.sql
Branch: sfcgal
Log Message:
ST_Intersect(geom, x, y, z, srid) has now a filter join implementation. Fix
leaks when the query aborts in ST_Intersects filer joins
diffs (truncated from 433 to 300 lines):
diff --git a/geom/monetdb5/geom.c b/geom/monetdb5/geom.c
--- a/geom/monetdb5/geom.c
+++ b/geom/monetdb5/geom.c
@@ -7577,8 +7577,13 @@ Intersectssubjoin_intern(bat *lres, bat
BATloop(br, pr, qr) {
wkb *rWKB = (wkb *) BUNtail(rBAT_iter, pr);
rGeometries[pr] = wkb2geos(rWKB);
- if ( !rGeometries[pr] )
+ if ( !rGeometries[pr] ) {
+ BBPunfix(*lid);
+ BBPunfix(*rid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
throw(MAL, "algebra.instersects", "wkb2geos failed");
+ }
}
lo = bl->hseqbase;
@@ -7591,8 +7596,17 @@ Intersectssubjoin_intern(bat *lres, bat
lWKB = (wkb *) BUNtail(lBAT_iter, pl);
lGeometry = wkb2geos(lWKB);
- if ( !lGeometry )
+ if ( !lGeometry ) {
+ for (j = 0; j < pl;j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*rid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
throw(MAL, "algebra.instersects", "wkb2geos failed");
+ }
lMBR = mbrFromGeos(lGeometry);
if (lMBR == NULL || mbr_isnil(lMBR)) {
@@ -7610,8 +7624,10 @@ Intersectssubjoin_intern(bat *lres, bat
if (!lGeometry ||!rGeometry) {
if (lGeometry)
GEOSGeom_destroy(lGeometry);
- if (rGeometry)
- GEOSGeom_destroy(rGeometry);
+ for (j = 0; j < BATcount(br);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
BBPunfix(*lid);
BBPunfix(*rid);
BBPunfix(xl->batCacheid);
@@ -7621,12 +7637,24 @@ Intersectssubjoin_intern(bat *lres, bat
if (GEOSGetSRID(lGeometry) != GEOSGetSRID(rGeometry)) {
GEOSGeom_destroy(lGeometry);
- GEOSGeom_destroy(rGeometry);
+ for (j = 0; j < BATcount(br);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*rid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
throw(MAL, "geom.Intersects", "Geometries of different SRID");
}
rMBR = mbrFromGeos(rGeometry);
if (rMBR == NULL || mbr_isnil(rMBR)) {
+ GEOSGeom_destroy(lGeometry);
+ for (j = 0; j < BATcount(br);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
BBPunfix(*lid);
BBPunfix(*rid);
BBPunfix(xl->batCacheid);
@@ -7635,7 +7663,13 @@ Intersectssubjoin_intern(bat *lres, bat
}
err = mbrOverlaps(&out, &lMBR, &rMBR);
- if (err != MAL_SUCCEED) {
+ if (err != MAL_SUCCEED) {
+ GEOSGeom_destroy(lGeometry);
+ for (j = 0; j < BATcount(br);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ GDKfree(rMBR);
BBPunfix(*lid);
BBPunfix(*rid);
BBPunfix(xl->batCacheid);
@@ -7645,8 +7679,16 @@ Intersectssubjoin_intern(bat *lres, bat
out = 0;
if ((out = GEOSIntersects(lGeometry, rGeometry)) == 2){
GEOSGeom_destroy(lGeometry);
- GEOSGeom_destroy(rGeometry);
- throw(MAL, "geom.Intersects", "GEOSIntersects
failed");
+ for (j = 0; j < BATcount(br);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ GDKfree(rMBR);
+ BBPunfix(*lid);
+ BBPunfix(*rid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ throw(MAL, "geom.Intersects", "GEOSIntersects failed");
}
if (out) {
BUNappend(xl, &lo, FALSE);
@@ -7689,3 +7731,295 @@ Intersectssubjoin(bat *lres, bat *rres,
return Intersectssubjoin_intern(lres, rres, lid, rid);
}
+static str
+IntersectsXYZsubjoin_intern(bat *lres, bat *rres, bat *lid, bat *xid, bat*yid,
bat *zid, int *srid)
+{
+ BAT *xl, *xr, *bl, *bx, *by, *bz;
+ oid lo, ro;
+ BATiter lBAT_iter, xBAT_iter, yBAT_iter, zBAT_iter;
+ uint32_t j = 0;
+ BUN px = 0, py = 0, pz =0, pl = 0, qx = 0, qy = 0, qz = 0, ql = 0;
+ GEOSGeom *rGeometries = NULL;
+
+ if( (bl= BATdescriptor(*lid)) == NULL )
+ throw(MAL, "algebra.instersects", RUNTIME_OBJECT_MISSING);
+
+ if( (bx= BATdescriptor(*xid)) == NULL ){
+ BBPunfix(*lid);
+ throw(MAL, "algebra.instersects", RUNTIME_OBJECT_MISSING);
+ }
+
+ if( (by= BATdescriptor(*yid)) == NULL ){
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ throw(MAL, "algebra.instersects", RUNTIME_OBJECT_MISSING);
+ }
+
+ if( (bz= BATdescriptor(*zid)) == NULL ){
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ throw(MAL, "algebra.instersects", RUNTIME_OBJECT_MISSING);
+ }
+
+ xl = COLnew(0, TYPE_oid, 0, TRANSIENT);
+ if ( xl == NULL){
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ throw(MAL, "algebra.instersects", MAL_MALLOC_FAIL);
+ }
+
+ xr = COLnew(0, TYPE_oid, 0, TRANSIENT);
+ if ( xr == NULL){
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ throw(MAL, "algebra.instersects", MAL_MALLOC_FAIL);
+ }
+
+ /*iterator over the BATs*/
+ lBAT_iter = bat_iterator(bl);
+ xBAT_iter = bat_iterator(bx);
+ yBAT_iter = bat_iterator(by);
+ zBAT_iter = bat_iterator(bz);
+
+ /*Get the Geometry for the inner BAT*/
+ rGeometries = (GEOSGeom*) GDKzalloc(sizeof(GEOSGeom) * BATcount(bx));
+ BATloop(bx, px, qx) {
+ GEOSGeom rGeos = NULL;
+ double *x, *y, *z;
+ GEOSCoordSeq seq;
+ x = (double*) BUNtail(xBAT_iter, px);
+ y = (double*) BUNtail(yBAT_iter, px);
+ z = (double*) BUNtail(zBAT_iter, px);
+
+ /*Create Geometry*/
+ if (*x == dbl_nil || *y == dbl_nil || *z == dbl_nil) {
+ rGeos = GEOSGeom_createEmptyPoint();
+ } else {
+ //create the point from the coordinates
+ seq = GEOSCoordSeq_create(1, 3);
+
+ if (seq == NULL) {
+ for (j = 0; j < px;j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ throw(MAL, "algebra.instersects", "GEOSCoordSeq_create
failed");
+ }
+
+ if (!GEOSCoordSeq_setOrdinate(seq, 0, 0, *x) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 1, *y) ||
+ !GEOSCoordSeq_setOrdinate(seq, 0, 2, *z)) {
+ for (j = 0; j < px;j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, "algebra.instersects", "GEOSCoordSeq_setOrdinate
failed");
+ }
+
+ if ((rGeos = GEOSGeom_createPoint(seq)) == NULL) {
+ for (j = 0; j < px;j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ GEOSCoordSeq_destroy(seq);
+ throw(MAL, "algebra.instersects", "Failed to create
GEOSGeometry from the coordinates");
+ }
+
+ if (*srid != int_nil)
+ GEOSSetSRID(rGeos, *srid);
+ }
+
+ rGeometries[px] = rGeos;
+ }
+
+ lo = bl->hseqbase;
+ BATloop(bl, pl, ql) {
+ str err = NULL;
+ wkb *lWKB = NULL;
+ mbr *lMBR = NULL;
+ GEOSGeom lGeometry = NULL;
+ ro = bx->hseqbase;
+
+ lWKB = (wkb *) BUNtail(lBAT_iter, pl);
+
+ lGeometry = wkb2geos(lWKB);
+ if ( !lGeometry ) {
+ for (j = 0; j < BATcount(bx);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ throw(MAL, "algebra.instersects", "wkb2geos failed");
+ }
+
+ lMBR = mbrFromGeos(lGeometry);
+ if (lMBR == NULL || mbr_isnil(lMBR)) {
+ for (j = 0; j < BATcount(bx);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ return err;
+ }
+
+ for (j = 0; j < BATcount(bx); j++, ro++) {
+ bit out = 0;
+ mbr *rMBR = NULL;
+ GEOSGeom rGeometry = rGeometries[j];
+ if (!lGeometry ||!rGeometry) {
+ if (lGeometry)
+ GEOSGeom_destroy(lGeometry);
+ for (j = 0; j < BATcount(bx);j++) {
+ GEOSGeom_destroy(rGeometries[j]);
+ }
+ GDKfree(rGeometries);
+ BBPunfix(*lid);
+ BBPunfix(*xid);
+ BBPunfix(*yid);
+ BBPunfix(*zid);
+ BBPunfix(xl->batCacheid);
+ BBPunfix(xr->batCacheid);
+ throw(MAL, "geom.IntersectsXYZ", "One of the geometries is
NULL");
+ }
+
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list