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

Reply via email to