LCOV - code coverage report
Current view: top level - geom/monetdb5 - geomBulk.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 351 764 45.9 %
Date: 2021-10-13 02:24:04 Functions: 31 39 79.5 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * Foteini Alvanaki
      11             :  */
      12             : 
      13             : #include "geom.h"
      14             : 
      15             : /*******************************/
      16             : /********** One input **********/
      17             : /*******************************/
      18             : 
      19             : str
      20           1 : geom_2_geom_bat(bat *outBAT_id, bat *inBAT_id, bat *cand, int *columnType, int *columnSRID)
      21             : {
      22             :         BAT *b = NULL, *s = NULL, *dst = NULL;
      23             :         BATiter bi;
      24             :         str msg = MAL_SUCCEED;
      25             :         struct canditer ci;
      26             :         BUN q = 0;
      27             :         oid off = 0;
      28             :         bool nils = false;
      29           1 :         wkb *inWKB = NULL, *outWKB = NULL;
      30             : 
      31             :         //get the descriptor of the BAT
      32           1 :         if ((b = BATdescriptor(*inBAT_id)) == NULL) {
      33           0 :                 msg = createException(MAL, "batcalc.wkb", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      34           0 :                 goto bailout;
      35             :         }
      36           1 :         bi = bat_iterator(b);
      37           1 :         if (cand && !is_bat_nil(*cand) && (s = BATdescriptor(*cand)) == NULL) {
      38           0 :                 msg = createException(MAL, "batcalc.wkb", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      39           0 :                 goto bailout;
      40             :         }
      41           1 :         off = b->hseqbase;
      42           1 :         q = canditer_init(&ci, b, s);
      43             :         //create a new BAT, aligned with input BAT
      44           1 :         if (!(dst = COLnew(ci.hseq, ATOMindex("wkb"), q, TRANSIENT))) {
      45           0 :                 msg = createException(MAL, "batcalc.wkb", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      46           0 :                 goto bailout;
      47             :         }
      48             : 
      49           1 :         if (ci.tpe == cand_dense) {
      50           4 :                 for (BUN i = 0; i < q; i++) {
      51           3 :                         oid p = (canditer_next_dense(&ci) - off);
      52           3 :                         inWKB = (wkb *) BUNtvar(bi, p);
      53             : 
      54           3 :                         if ((msg = geom_2_geom(&outWKB, &inWKB, columnType, columnSRID)) != MAL_SUCCEED)        //check type
      55           0 :                                 goto bailout;
      56           3 :                         if (tfastins_nocheckVAR(dst, i, outWKB) != GDK_SUCCEED) {
      57           0 :                                 GDKfree(outWKB);
      58           0 :                                 msg = createException(MAL, "batcalc.wkb", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      59           0 :                                 goto bailout;
      60             :                         }
      61           3 :                         nils |= is_wkb_nil(outWKB);
      62           3 :                         GDKfree(outWKB);
      63           3 :                         outWKB = NULL;
      64             :                 }
      65             :         } else {
      66           0 :                 for (BUN i = 0; i < q; i++) {
      67           0 :                         oid p = (canditer_next(&ci) - off);
      68           0 :                         inWKB = (wkb *) BUNtvar(bi, p);
      69             : 
      70           0 :                         if ((msg = geom_2_geom(&outWKB, &inWKB, columnType, columnSRID)) != MAL_SUCCEED)        //check type
      71           0 :                                 goto bailout;
      72           0 :                         if (tfastins_nocheckVAR(dst, i, outWKB) != GDK_SUCCEED) {
      73           0 :                                 GDKfree(outWKB);
      74           0 :                                 msg = createException(MAL, "batcalc.wkb", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      75           0 :                                 goto bailout;
      76             :                         }
      77           0 :                         nils |= is_wkb_nil(outWKB);
      78           0 :                         GDKfree(outWKB);
      79           0 :                         outWKB = NULL;
      80             :                 }
      81             :         }
      82             : 
      83           0 : bailout:
      84           1 :         if (b) {
      85           1 :                 bat_iterator_end(&bi);
      86           1 :                 BBPunfix(b->batCacheid);
      87             :         }
      88           1 :         if (s)
      89           0 :                 BBPunfix(s->batCacheid);
      90           1 :         if (dst && !msg) {
      91           1 :                 BATsetcount(dst, q);
      92           1 :                 dst->tnil = nils;
      93           1 :                 dst->tnonil = !nils;
      94           1 :                 dst->tkey = BATcount(dst) <= 1;
      95           1 :                 dst->tsorted = BATcount(dst) <= 1;
      96           1 :                 dst->trevsorted = BATcount(dst) <= 1;
      97           1 :                 BBPkeepref(*outBAT_id = dst->batCacheid);
      98           0 :         } else if (dst)
      99           0 :                 BBPreclaim(dst);
     100           1 :         return msg;
     101             : }
     102             : 
     103             : /*create WKB from WKT */
     104             : str
     105          49 : wkbFromText_bat(bat *outBAT_id, bat *inBAT_id, int *srid, int *tpe)
     106             : {
     107          49 :         return wkbFromText_bat_cand(outBAT_id, inBAT_id, NULL, srid, tpe);
     108             : }
     109             : 
     110             : str
     111          53 : wkbFromText_bat_cand(bat *outBAT_id, bat *inBAT_id, bat *cand, int *srid, int *tpe)
     112             : {
     113             :         BAT *b = NULL, *s = NULL, *dst = NULL;
     114             :         BATiter bi;
     115             :         str msg = MAL_SUCCEED;
     116             :         struct canditer ci;
     117             :         BUN q = 0;
     118             :         oid off = 0;
     119             :         bool nils = false;
     120             : 
     121             :         //get the descriptor of the BAT
     122          53 :         if ((b = BATdescriptor(*inBAT_id)) == NULL) {
     123           0 :                 msg = createException(MAL, "batgeom.wkbFromText", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     124           0 :                 goto bailout;
     125             :         }
     126          53 :         bi = bat_iterator(b);
     127          53 :         if (cand && !is_bat_nil(*cand) && (s = BATdescriptor(*cand)) == NULL) {
     128           0 :                 msg = createException(MAL, "batgeom.wkbFromText", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     129           0 :                 goto bailout;
     130             :         }
     131          53 :         off = b->hseqbase;
     132          53 :         q = canditer_init(&ci, b, s);
     133             :         //create a new BAT, aligned with input BAT
     134          53 :         if (!(dst = COLnew(ci.hseq, ATOMindex("wkb"), q, TRANSIENT))) {
     135           0 :                 msg = createException(MAL, "batgeom.wkbFromText", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     136           0 :                 goto bailout;
     137             :         }
     138             : 
     139          53 :         if (ci.tpe == cand_dense) {
     140          78 :                 for (BUN i = 0; i < q; i++) {
     141          68 :                         oid p = (canditer_next_dense(&ci) - off);
     142          68 :                         str inWKB = (str) BUNtvar(bi, p);
     143             :                         wkb *outSingle;
     144             : 
     145          68 :                         if ((msg = wkbFromText(&outSingle, &inWKB, srid, tpe)) != MAL_SUCCEED)
     146          43 :                                 goto bailout;
     147          25 :                         if (tfastins_nocheckVAR(dst, i, outSingle) != GDK_SUCCEED) {
     148           0 :                                 GDKfree(outSingle);
     149           0 :                                 msg = createException(MAL, "batgeom.wkbFromText", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     150           0 :                                 goto bailout;
     151             :                         }
     152          25 :                         nils |= is_wkb_nil(outSingle);
     153          25 :                         GDKfree(outSingle);
     154             :                         outSingle = NULL;
     155             :                 }
     156             :         } else {
     157           0 :                 for (BUN i = 0; i < q; i++) {
     158           0 :                         oid p = (canditer_next(&ci) - off);
     159           0 :                         str inWKB = (str) BUNtvar(bi, p);
     160             :                         wkb *outSingle;
     161             : 
     162           0 :                         if ((msg = wkbFromText(&outSingle, &inWKB, srid, tpe)) != MAL_SUCCEED)
     163           0 :                                 goto bailout;
     164           0 :                         if (tfastins_nocheckVAR(dst, i, outSingle) != GDK_SUCCEED) {
     165           0 :                                 GDKfree(outSingle);
     166           0 :                                 msg = createException(MAL, "batgeom.wkbFromText", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     167           0 :                                 goto bailout;
     168             :                         }
     169           0 :                         nils |= is_wkb_nil(outSingle);
     170           0 :                         GDKfree(outSingle);
     171             :                         outSingle = NULL;
     172             :                 }
     173             :         }
     174             : 
     175           0 : bailout:
     176          53 :         if (b) {
     177          53 :                 bat_iterator_end(&bi);
     178          53 :                 BBPunfix(b->batCacheid);
     179             :         }
     180          53 :         if (s)
     181           0 :                 BBPunfix(s->batCacheid);
     182          53 :         if (dst && !msg) {
     183          10 :                 BATsetcount(dst, q);
     184          10 :                 dst->tnil = nils;
     185          10 :                 dst->tnonil = !nils;
     186          10 :                 dst->tkey = BATcount(dst) <= 1;
     187          10 :                 dst->tsorted = BATcount(dst) <= 1;
     188          10 :                 dst->trevsorted = BATcount(dst) <= 1;
     189          10 :                 BBPkeepref(*outBAT_id = dst->batCacheid);
     190          43 :         } else if (dst)
     191          43 :                 BBPreclaim(dst);
     192          53 :         return msg;
     193             : }
     194             : 
     195             : /*****************************************************************************/
     196             : /********************* IN: mbr - OUT: double - FLAG :int *********************/
     197             : /*****************************************************************************/
     198             : str
     199           8 : wkbCoordinateFromMBR_bat(bat *outBAT_id, bat *inBAT_id, int *coordinateIdx)
     200             : {
     201             :         BAT *outBAT = NULL, *inBAT = NULL;
     202           8 :         mbr *inMBR = NULL;
     203           8 :         double outDbl = 0.0;
     204             :         BUN p = 0, q = 0;
     205             :         BATiter inBAT_iter;
     206             : 
     207             :         //get the descriptor of the BAT
     208           8 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     209           0 :                 throw(MAL, "batgeom.coordinateFromMBR", SQLSTATE(38000) RUNTIME_OBJECT_MISSING);
     210             :         }
     211             : 
     212             :         //create a new BAT for the output
     213           8 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("dbl"), BATcount(inBAT), TRANSIENT)) == NULL) {
     214           0 :                 BBPunfix(inBAT->batCacheid);
     215           0 :                 throw(MAL, "batgeom.coordinateFromMBR", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     216             :         }
     217             : 
     218             :         //iterator over the BAT
     219           8 :         inBAT_iter = bat_iterator(inBAT);
     220         223 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     221             :                 str err = NULL;
     222             : 
     223         215 :                 inMBR = (mbr *) BUNtloc(inBAT_iter, p);
     224         215 :                 if ((err = wkbCoordinateFromMBR(&outDbl, &inMBR, coordinateIdx)) != MAL_SUCCEED) {
     225           0 :                         bat_iterator_end(&inBAT_iter);
     226           0 :                         BBPunfix(inBAT->batCacheid);
     227           0 :                         BBPunfix(outBAT->batCacheid);
     228           0 :                         return err;
     229             :                 }
     230         215 :                 if (BUNappend(outBAT, &outDbl, false) != GDK_SUCCEED) {
     231           0 :                         bat_iterator_end(&inBAT_iter);
     232           0 :                         BBPunfix(inBAT->batCacheid);
     233           0 :                         BBPunfix(outBAT->batCacheid);
     234           0 :                         throw(MAL, "batgeom.coordinateFromMBR", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     235             :                 }
     236             :         }
     237           8 :         bat_iterator_end(&inBAT_iter);
     238             : 
     239           8 :         BBPunfix(inBAT->batCacheid);
     240           8 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     241           8 :         return MAL_SUCCEED;
     242             : 
     243             : }
     244             : 
     245             : /**************************************************************************/
     246             : /********************* IN: wkb - OUT: str - FLAG :int *********************/
     247             : /**************************************************************************/
     248             : static str
     249          40 : WKBtoSTRflagINT_bat(bat *outBAT_id, bat *inBAT_id, int *flag, str (*func) (char **, wkb **, int *), const char *name)
     250             : {
     251             :         BAT *outBAT = NULL, *inBAT = NULL;
     252          40 :         wkb *inWKB = NULL;
     253             :         BUN p = 0, q = 0;
     254             :         BATiter inBAT_iter;
     255             : 
     256             :         //get the descriptor of the BAT
     257          40 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     258           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     259             :         }
     260             : 
     261             :         //create a new for the output BAT
     262          40 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("str"), BATcount(inBAT), TRANSIENT)) == NULL) {
     263           0 :                 BBPunfix(inBAT->batCacheid);
     264           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     265             :         }
     266             : 
     267             :         //iterator over the input BAT
     268          40 :         inBAT_iter = bat_iterator(inBAT);
     269         121 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     270             :                 str err = NULL;
     271             :                 char *outSingle;
     272             : 
     273          81 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     274          81 :                 if ((err = (*func) (&outSingle, &inWKB, flag)) != MAL_SUCCEED) {
     275           0 :                         bat_iterator_end(&inBAT_iter);
     276           0 :                         BBPunfix(inBAT->batCacheid);
     277           0 :                         BBPunfix(outBAT->batCacheid);
     278           0 :                         return err;
     279             :                 }
     280          81 :                 if (BUNappend(outBAT, outSingle, false) != GDK_SUCCEED) {
     281           0 :                         bat_iterator_end(&inBAT_iter);
     282           0 :                         BBPunfix(inBAT->batCacheid);
     283           0 :                         BBPunfix(outBAT->batCacheid);
     284           0 :                         GDKfree(outSingle);
     285           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     286             :                 }
     287          81 :                 GDKfree(outSingle);
     288             :                 outSingle = NULL;
     289             :         }
     290          40 :         bat_iterator_end(&inBAT_iter);
     291             : 
     292             :         //set the number of elements in the outBAT
     293          40 :         BATsetcount(outBAT, BATcount(inBAT));
     294             : 
     295          40 :         BBPunfix(inBAT->batCacheid);
     296          40 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     297             : 
     298          40 :         return MAL_SUCCEED;
     299             : }
     300             : 
     301             : /*create textual representation of the wkb */
     302             : str
     303          27 : wkbAsText_bat(bat *outBAT_id, bat *inBAT_id, int *withSRID)
     304             : {
     305          27 :         return WKBtoSTRflagINT_bat(outBAT_id, inBAT_id, withSRID, wkbAsText, "batgeom.wkbAsText");
     306             : }
     307             : 
     308             : str
     309          13 : wkbGeometryType_bat(bat *outBAT_id, bat *inBAT_id, int *flag)
     310             : {
     311          13 :         return WKBtoSTRflagINT_bat(outBAT_id, inBAT_id, flag, wkbGeometryType, "batgeom.wkbGeometryType");
     312             : }
     313             : 
     314             : /***************************************************************************/
     315             : /*************************** IN: wkb - OUT: wkb ****************************/
     316             : /***************************************************************************/
     317             : 
     318             : static str
     319           5 : WKBtoWKB_bat(bat *outBAT_id, bat *inBAT_id, str (*func) (wkb **, wkb **), const char *name)
     320             : {
     321             :         BAT *outBAT = NULL, *inBAT = NULL;
     322           5 :         wkb *inWKB = NULL;
     323             :         BUN p = 0, q = 0;
     324             :         BATiter inBAT_iter;
     325             : 
     326             :         //get the descriptor of the BAT
     327           5 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     328           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     329             :         }
     330             : 
     331             :         //create a new for the output BAT
     332           5 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("wkb"), BATcount(inBAT), TRANSIENT)) == NULL) {
     333           0 :                 BBPunfix(inBAT->batCacheid);
     334           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     335             :         }
     336             : 
     337             :         //iterator over the input BAT
     338           5 :         inBAT_iter = bat_iterator(inBAT);
     339          29 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     340             :                 str err = NULL;
     341             :                 wkb *outSingle;
     342             : 
     343          24 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     344          24 :                 if ((err = (*func) (&outSingle, &inWKB)) != MAL_SUCCEED) {
     345           0 :                         bat_iterator_end(&inBAT_iter);
     346           0 :                         BBPunfix(inBAT->batCacheid);
     347           0 :                         BBPunfix(outBAT->batCacheid);
     348           0 :                         return err;
     349             :                 }
     350          24 :                 if (BUNappend(outBAT, outSingle, false) != GDK_SUCCEED) {
     351           0 :                         bat_iterator_end(&inBAT_iter);
     352           0 :                         BBPunfix(inBAT->batCacheid);
     353           0 :                         BBPunfix(outBAT->batCacheid);
     354           0 :                         GDKfree(outSingle);
     355           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     356             :                 }
     357          24 :                 GDKfree(outSingle);
     358             :                 outSingle = NULL;
     359             :         }
     360           5 :         bat_iterator_end(&inBAT_iter);
     361             : 
     362             :         //set the number of elements in the outBAT
     363           5 :         BATsetcount(outBAT, BATcount(inBAT));
     364             : 
     365           5 :         BBPunfix(inBAT->batCacheid);
     366           5 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     367             : 
     368           5 :         return MAL_SUCCEED;
     369             : }
     370             : 
     371             : str
     372           5 : wkbBoundary_bat(bat *outBAT_id, bat *inBAT_id)
     373             : {
     374           5 :         return WKBtoWKB_bat(outBAT_id, inBAT_id, wkbBoundary, "batgeom.wkbBoundary");
     375             : }
     376             : 
     377             : 
     378             : /**************************************************************************************/
     379             : /*************************** IN: wkb - OUT: wkb - FLAG:int ****************************/
     380             : /**************************************************************************************/
     381             : 
     382             : static str
     383           5 : WKBtoWKBflagINT_bat(bat *outBAT_id, bat *inBAT_id, const int *flag, str (*func) (wkb **, wkb **, const int *), const char *name)
     384             : {
     385             :         BAT *outBAT = NULL, *inBAT = NULL;
     386           5 :         wkb *inWKB = NULL;
     387             :         BUN p = 0, q = 0;
     388             :         BATiter inBAT_iter;
     389             : 
     390             :         //get the descriptor of the BAT
     391           5 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     392           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     393             :         }
     394             : 
     395             :         //create a new for the output BAT
     396           5 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("wkb"), BATcount(inBAT), TRANSIENT)) == NULL) {
     397           0 :                 BBPunfix(inBAT->batCacheid);
     398           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     399             :         }
     400             : 
     401             :         //iterator over the input BAT
     402           5 :         inBAT_iter = bat_iterator(inBAT);
     403          13 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     404             :                 str err = NULL;
     405             :                 wkb *outSingle;
     406             : 
     407           8 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     408           8 :                 if ((err = (*func) (&outSingle, &inWKB, flag)) != MAL_SUCCEED) {
     409           0 :                         bat_iterator_end(&inBAT_iter);
     410           0 :                         BBPunfix(inBAT->batCacheid);
     411           0 :                         BBPunfix(outBAT->batCacheid);
     412           0 :                         return err;
     413             :                 }
     414           8 :                 if (BUNappend(outBAT, outSingle, false) != GDK_SUCCEED) {
     415           0 :                         bat_iterator_end(&inBAT_iter);
     416           0 :                         BBPunfix(inBAT->batCacheid);
     417           0 :                         BBPunfix(outBAT->batCacheid);
     418           0 :                         GDKfree(outSingle);
     419           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     420             :                 }
     421           8 :                 GDKfree(outSingle);
     422             :                 outSingle = NULL;
     423             :         }
     424           5 :         bat_iterator_end(&inBAT_iter);
     425             : 
     426             :         //set the number of elements in the outBAT
     427           5 :         BATsetcount(outBAT, BATcount(inBAT));
     428             : 
     429           5 :         BBPunfix(inBAT->batCacheid);
     430           5 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     431             : 
     432           5 :         return MAL_SUCCEED;
     433             : }
     434             : 
     435             : str
     436           5 : wkbGeometryN_bat(bat *outBAT_id, bat *inBAT_id, const int *flag)
     437             : {
     438           5 :         return WKBtoWKBflagINT_bat(outBAT_id, inBAT_id, flag, wkbGeometryN, "batgeom.wkbGeometryN");
     439             : }
     440             : 
     441             : /***************************************************************************/
     442             : /*************************** IN: wkb - OUT: bit ****************************/
     443             : /***************************************************************************/
     444             : 
     445             : static str
     446          29 : WKBtoBIT_bat(bat *outBAT_id, bat *inBAT_id, str (*func) (bit *, wkb **), const char *name)
     447             : {
     448             :         BAT *outBAT = NULL, *inBAT = NULL;
     449          29 :         wkb *inWKB = NULL;
     450             :         BUN p = 0, q = 0;
     451             :         BATiter inBAT_iter;
     452             : 
     453             :         //get the descriptor of the BAT
     454          29 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     455           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     456             :         }
     457             : 
     458             :         //create a new for the output BAT
     459          29 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("bit"), BATcount(inBAT), TRANSIENT)) == NULL) {
     460           0 :                 BBPunfix(inBAT->batCacheid);
     461           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     462             :         }
     463             : 
     464             :         //iterator over the input BAT
     465          29 :         inBAT_iter = bat_iterator(inBAT);
     466         117 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     467             :                 str err = NULL;
     468             :                 bit outSingle;
     469             : 
     470          88 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     471          88 :                 if ((err = (*func) (&outSingle, &inWKB)) != MAL_SUCCEED) {
     472           0 :                         bat_iterator_end(&inBAT_iter);
     473           0 :                         BBPunfix(inBAT->batCacheid);
     474           0 :                         BBPunfix(outBAT->batCacheid);
     475           0 :                         return err;
     476             :                 }
     477          88 :                 if (BUNappend(outBAT, &outSingle, false) != GDK_SUCCEED) {
     478           0 :                         bat_iterator_end(&inBAT_iter);
     479           0 :                         BBPunfix(inBAT->batCacheid);
     480           0 :                         BBPunfix(outBAT->batCacheid);
     481           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     482             :                 }
     483             :         }
     484          29 :         bat_iterator_end(&inBAT_iter);
     485             : 
     486             :         //set the number of elements in the outBAT
     487          29 :         BATsetcount(outBAT, BATcount(inBAT));
     488             : 
     489          29 :         BBPunfix(inBAT->batCacheid);
     490          29 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     491             : 
     492          29 :         return MAL_SUCCEED;
     493             : 
     494             : }
     495             : 
     496             : str
     497           7 : wkbIsClosed_bat(bat *outBAT_id, bat *inBAT_id)
     498             : {
     499           7 :         return WKBtoBIT_bat(outBAT_id, inBAT_id, wkbIsClosed, "batgeom.wkbIsClosed");
     500             : }
     501             : 
     502             : str
     503           5 : wkbIsEmpty_bat(bat *outBAT_id, bat *inBAT_id)
     504             : {
     505           5 :         return WKBtoBIT_bat(outBAT_id, inBAT_id, wkbIsEmpty, "batgeom.wkbIsEmpty");
     506             : }
     507             : 
     508             : str
     509           7 : wkbIsSimple_bat(bat *outBAT_id, bat *inBAT_id)
     510             : {
     511           7 :         return WKBtoBIT_bat(outBAT_id, inBAT_id, wkbIsSimple, "batgeom.wkbIsSimple");
     512             : }
     513             : 
     514             : str
     515           4 : wkbIsRing_bat(bat *outBAT_id, bat *inBAT_id)
     516             : {
     517           4 :         return WKBtoBIT_bat(outBAT_id, inBAT_id, wkbIsRing, "batgeom.wkbIsRing");
     518             : }
     519             : 
     520             : str
     521           6 : wkbIsValid_bat(bat *outBAT_id, bat *inBAT_id)
     522             : {
     523           6 :         return WKBtoBIT_bat(outBAT_id, inBAT_id, wkbIsValid, "batgeom.wkbIsValid");
     524             : }
     525             : 
     526             : 
     527             : /***************************************************************************/
     528             : /*************************** IN: wkb - OUT: int ****************************/
     529             : /***************************************************************************/
     530             : 
     531             : static str
     532          10 : WKBtoINT_bat(bat *outBAT_id, bat *inBAT_id, str (*func) (int *, wkb **), const char *name)
     533             : {
     534             :         BAT *outBAT = NULL, *inBAT = NULL;
     535          10 :         wkb *inWKB = NULL;
     536             :         BUN p = 0, q = 0;
     537             :         BATiter inBAT_iter;
     538             : 
     539             :         //get the descriptor of the BAT
     540          10 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     541           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     542             :         }
     543             : 
     544             :         //create a new for the output BAT
     545          10 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("int"), BATcount(inBAT), TRANSIENT)) == NULL) {
     546           0 :                 BBPunfix(inBAT->batCacheid);
     547           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     548             :         }
     549             : 
     550             :         //iterator over the input BAT
     551          10 :         inBAT_iter = bat_iterator(inBAT);
     552          46 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     553             :                 str err = NULL;
     554             :                 int outSingle;
     555             : 
     556          36 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     557          36 :                 if ((err = (*func) (&outSingle, &inWKB)) != MAL_SUCCEED) {
     558           0 :                         bat_iterator_end(&inBAT_iter);
     559           0 :                         BBPunfix(inBAT->batCacheid);
     560           0 :                         BBPunfix(outBAT->batCacheid);
     561           0 :                         return err;
     562             :                 }
     563          36 :                 if (BUNappend(outBAT, &outSingle, false) != GDK_SUCCEED) {
     564           0 :                         bat_iterator_end(&inBAT_iter);
     565           0 :                         BBPunfix(inBAT->batCacheid);
     566           0 :                         BBPunfix(outBAT->batCacheid);
     567           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     568             :                 }
     569             :         }
     570          10 :         bat_iterator_end(&inBAT_iter);
     571             : 
     572             :         //set the number of elements in the outBAT
     573          10 :         BATsetcount(outBAT, BATcount(inBAT));
     574             : 
     575          10 :         BBPunfix(inBAT->batCacheid);
     576          10 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     577             : 
     578          10 :         return MAL_SUCCEED;
     579             : 
     580             : }
     581             : 
     582             : str
     583           5 : wkbDimension_bat(bat *outBAT_id, bat *inBAT_id)
     584             : {
     585           5 :         return WKBtoINT_bat(outBAT_id, inBAT_id, wkbDimension, "batgeom.wkbDimension");
     586             : }
     587             : 
     588             : str
     589           5 : wkbNumGeometries_bat(bat *outBAT_id, bat *inBAT_id)
     590             : {
     591           5 :         return WKBtoINT_bat(outBAT_id, inBAT_id, wkbNumGeometries, "batgeom.wkbNumGeometries");
     592             : }
     593             : 
     594             : /***************************************************************************************/
     595             : /*************************** IN: wkb - OUT: int - FLAG: int ****************************/
     596             : /***************************************************************************************/
     597             : 
     598             : static str
     599          18 : WKBtoINTflagINT_bat(bat *outBAT_id, bat *inBAT_id, int *flag, str (*func) (int *, wkb **, int *), const char *name)
     600             : {
     601             :         BAT *outBAT = NULL, *inBAT = NULL;
     602          18 :         wkb *inWKB = NULL;
     603             :         BUN p = 0, q = 0;
     604             :         BATiter inBAT_iter;
     605             : 
     606             :         //get the descriptor of the BAT
     607          18 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     608           0 :                 throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     609             :         }
     610             : 
     611             :         //create a new for the output BAT
     612          18 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("int"), BATcount(inBAT), TRANSIENT)) == NULL) {
     613           0 :                 BBPunfix(inBAT->batCacheid);
     614           0 :                 throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     615             :         }
     616             : 
     617             :         //iterator over the input BAT
     618          18 :         inBAT_iter = bat_iterator(inBAT);
     619          52 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     620             :                 str err = NULL;
     621             :                 int outSingle;
     622             : 
     623          34 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     624          34 :                 if ((err = (*func) (&outSingle, &inWKB, flag)) != MAL_SUCCEED) {
     625           0 :                         bat_iterator_end(&inBAT_iter);
     626           0 :                         BBPunfix(inBAT->batCacheid);
     627           0 :                         BBPunfix(outBAT->batCacheid);
     628           0 :                         return err;
     629             :                 }
     630          34 :                 if (BUNappend(outBAT, &outSingle, false) != GDK_SUCCEED) {
     631           0 :                         bat_iterator_end(&inBAT_iter);
     632           0 :                         BBPunfix(inBAT->batCacheid);
     633           0 :                         BBPunfix(outBAT->batCacheid);
     634           0 :                         throw(MAL, name, SQLSTATE(HY013) MAL_MALLOC_FAIL);
     635             :                 }
     636             :         }
     637          18 :         bat_iterator_end(&inBAT_iter);
     638             : 
     639             :         //set the number of elements in the outBAT
     640          18 :         BATsetcount(outBAT, BATcount(inBAT));
     641             : 
     642          18 :         BBPunfix(inBAT->batCacheid);
     643          18 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     644             : 
     645          18 :         return MAL_SUCCEED;
     646             : 
     647             : }
     648             : 
     649             : str
     650           9 : wkbNumPoints_bat(bat *outBAT_id, bat *inBAT_id, int *flag)
     651             : {
     652           9 :         return WKBtoINTflagINT_bat(outBAT_id, inBAT_id, flag, wkbNumPoints, "batgeom.wkbNumPoints");
     653             : }
     654             : 
     655             : str
     656           9 : wkbNumRings_bat(bat *outBAT_id, bat *inBAT_id, int *flag)
     657             : {
     658           9 :         return WKBtoINTflagINT_bat(outBAT_id, inBAT_id, flag, wkbNumRings, "batgeom.wkbNumRings");
     659             : }
     660             : 
     661             : /******************************************************************************************/
     662             : /*************************** IN: wkb - OUT: double - FLAG: int ****************************/
     663             : /******************************************************************************************/
     664             : 
     665             : str
     666          12 : wkbGetCoordinate_bat(bat *outBAT_id, bat *inBAT_id, int *flag)
     667             : {
     668             :         BAT *outBAT = NULL, *inBAT = NULL;
     669          12 :         wkb *inWKB = NULL;
     670             :         BUN p = 0, q = 0;
     671             :         BATiter inBAT_iter;
     672             : 
     673             :         //get the descriptor of the BAT
     674          12 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     675           0 :                 throw(MAL, "batgeom.wkbGetCoordinate", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     676             :         }
     677             : 
     678             :         //create a new for the output BAT
     679          12 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("dbl"), BATcount(inBAT), TRANSIENT)) == NULL) {
     680           0 :                 BBPunfix(inBAT->batCacheid);
     681           0 :                 throw(MAL, "batgeom.wkbGetCoordinate", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     682             :         }
     683             : 
     684             :         //iterator over the input BAT
     685          12 :         inBAT_iter = bat_iterator(inBAT);
     686          30 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
     687             :                 str err = NULL;
     688             :                 double outSingle;
     689             : 
     690          22 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     691          22 :                 if ((err = wkbGetCoordinate(&outSingle, &inWKB, flag)) != MAL_SUCCEED) {
     692           4 :                         bat_iterator_end(&inBAT_iter);
     693           4 :                         BBPunfix(inBAT->batCacheid);
     694           4 :                         BBPunfix(outBAT->batCacheid);
     695           4 :                         return err;
     696             :                 }
     697          18 :                 if (BUNappend(outBAT, &outSingle, false) != GDK_SUCCEED) {
     698           0 :                         bat_iterator_end(&inBAT_iter);
     699           0 :                         BBPunfix(inBAT->batCacheid);
     700           0 :                         BBPunfix(outBAT->batCacheid);
     701           0 :                         throw(MAL, "batgeom.wkbGetCoordinate", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     702             :                 }
     703             :         }
     704           8 :         bat_iterator_end(&inBAT_iter);
     705             : 
     706             :         //set the number of elements in the outBAT
     707           8 :         BATsetcount(outBAT, BATcount(inBAT));
     708             : 
     709           8 :         BBPunfix(inBAT->batCacheid);
     710           8 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     711             : 
     712           8 :         return MAL_SUCCEED;
     713             : 
     714             : }
     715             : 
     716             : /*******************************/
     717             : /********* Two inputs **********/
     718             : /*******************************/
     719             : 
     720             : str
     721           1 : wkbBox2D_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id)
     722             : {
     723             :         BAT *outBAT = NULL, *aBAT = NULL, *bBAT = NULL;
     724             :         BATiter aBAT_iter, bBAT_iter;
     725             :         BUN i = 0;
     726             :         str ret = MAL_SUCCEED;
     727             : 
     728             :         //get the BATs
     729           1 :         if ((aBAT = BATdescriptor(*aBAT_id)) == NULL || (bBAT = BATdescriptor(*bBAT_id)) == NULL) {
     730           0 :                 ret = createException(MAL, "batgeom.wkbBox2D", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     731           0 :                 goto clean;
     732             :         }
     733             :         //check if the BATs are aligned
     734           1 :         if (aBAT->hseqbase != bBAT->hseqbase || BATcount(aBAT) != BATcount(bBAT)) {
     735           0 :                 ret = createException(MAL, "batgeom.wkbBox2D", SQLSTATE(38000) "Columns must be aligned");
     736           0 :                 goto clean;
     737             :         }
     738             :         //create a new BAT for the output
     739           1 :         if ((outBAT = COLnew(aBAT->hseqbase, ATOMindex("mbr"), BATcount(aBAT), TRANSIENT)) == NULL) {
     740           0 :                 ret = createException(MAL, "batgeom.wkbBox2D", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     741           0 :                 goto clean;
     742             :         }
     743             : 
     744             :         //iterator over the BATs
     745           1 :         aBAT_iter = bat_iterator(aBAT);
     746           1 :         bBAT_iter = bat_iterator(bBAT);
     747             : 
     748          17 :         for (i = 0; i < BATcount(aBAT); i++) {
     749             :                 mbr *outSingle;
     750             : 
     751          16 :                 wkb *aWKB = (wkb *) BUNtvar(aBAT_iter, i);
     752          16 :                 wkb *bWKB = (wkb *) BUNtvar(bBAT_iter, i);
     753             : 
     754          16 :                 if ((ret = wkbBox2D(&outSingle, &aWKB, &bWKB)) != MAL_SUCCEED) {
     755           0 :                         BBPreclaim(outBAT);
     756           0 :                         goto bailout;
     757             :                 }
     758          16 :                 if (BUNappend(outBAT, outSingle, false) != GDK_SUCCEED) {
     759           0 :                         BBPreclaim(outBAT);
     760           0 :                         GDKfree(outSingle);
     761           0 :                         ret = createException(MAL, "batgeom.wkbBox2D", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     762           0 :                         goto bailout;
     763             :                 }
     764          16 :                 GDKfree(outSingle);
     765             :         }
     766             : 
     767           1 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     768           1 :   bailout:
     769           1 :         bat_iterator_end(&aBAT_iter);
     770           1 :         bat_iterator_end(&bBAT_iter);
     771             : 
     772           1 :   clean:
     773           1 :         if (aBAT)
     774           1 :                 BBPunfix(aBAT->batCacheid);
     775           1 :         if (bBAT)
     776           1 :                 BBPunfix(bBAT->batCacheid);
     777             : 
     778           1 :         return ret;
     779             : }
     780             : 
     781             : str
     782           4 : wkbContains_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id)
     783             : {
     784             :         BAT *outBAT = NULL, *aBAT = NULL, *bBAT = NULL;
     785             :         BATiter aBAT_iter, bBAT_iter;
     786             :         BUN i = 0;
     787             :         str ret = MAL_SUCCEED;
     788             : 
     789             :         //get the BATs
     790           4 :         if ((aBAT = BATdescriptor(*aBAT_id)) == NULL || (bBAT = BATdescriptor(*bBAT_id)) == NULL) {
     791           0 :                 ret = createException(MAL, "batgeom.Contains", SQLSTATE(38000) "Problem retrieving BATs");
     792           0 :                 goto clean;
     793             :         }
     794             :         //check if the BATs are aligned
     795           4 :         if (aBAT->hseqbase != bBAT->hseqbase || BATcount(aBAT) != BATcount(bBAT)) {
     796           0 :                 ret = createException(MAL, "batgeom.Contains", SQLSTATE(38000) "Columns must be aligned");
     797           0 :                 goto clean;
     798             :         }
     799             :         //create a new BAT for the output
     800           4 :         if ((outBAT = COLnew(aBAT->hseqbase, ATOMindex("bit"), BATcount(aBAT), TRANSIENT)) == NULL) {
     801           0 :                 ret = createException(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     802           0 :                 goto clean;
     803             :         }
     804             : 
     805             :         //iterator over the BATs
     806           4 :         aBAT_iter = bat_iterator(aBAT);
     807           4 :         bBAT_iter = bat_iterator(bBAT);
     808             : 
     809           9 :         for (i = 0; i < BATcount(aBAT); i++) {
     810             :                 bit outBIT;
     811             : 
     812           5 :                 wkb *aWKB = (wkb *) BUNtvar(aBAT_iter, i);
     813           5 :                 wkb *bWKB = (wkb *) BUNtvar(bBAT_iter, i);
     814             : 
     815           5 :                 if ((ret = wkbContains(&outBIT, &aWKB, &bWKB)) != MAL_SUCCEED) {
     816           0 :                         BBPreclaim(outBAT);
     817           0 :                         goto bailout;
     818             :                 }
     819           5 :                 if (BUNappend(outBAT, &outBIT, false) != GDK_SUCCEED) {
     820           0 :                         BBPreclaim(outBAT);
     821           0 :                         ret = createException(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     822           0 :                         goto bailout;
     823             :                 }
     824             :         }
     825             : 
     826           4 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     827             : 
     828           4 :   bailout:
     829           4 :         bat_iterator_end(&aBAT_iter);
     830           4 :         bat_iterator_end(&bBAT_iter);
     831             : 
     832           4 :   clean:
     833           4 :         if (aBAT)
     834           4 :                 BBPunfix(aBAT->batCacheid);
     835           4 :         if (bBAT)
     836           4 :                 BBPunfix(bBAT->batCacheid);
     837             : 
     838           4 :         return ret;
     839             : }
     840             : 
     841             : str
     842           0 : wkbContains_geom_bat(bat *outBAT_id, wkb **geomWKB, bat *inBAT_id)
     843             : {
     844             :         BAT *outBAT = NULL, *inBAT = NULL;
     845             :         BATiter inBAT_iter;
     846             :         BUN p = 0, q = 0;
     847             : 
     848             :         //get the descriptor of the BAT
     849           0 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     850           0 :                 throw(MAL, "batgeom.Contains", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     851             :         }
     852             : 
     853             :         //create a new BAT for the output
     854           0 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("bit"), BATcount(inBAT), TRANSIENT)) == NULL) {
     855           0 :                 BBPunfix(inBAT->batCacheid);
     856           0 :                 throw(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     857             :         }
     858             : 
     859             :         //iterator over the BATs
     860           0 :         inBAT_iter = bat_iterator(inBAT);
     861           0 :         BATloop(inBAT, p, q) {
     862             :                 str err = NULL;
     863             :                 bit outBIT;
     864             : 
     865           0 :                 wkb *inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     866             : 
     867           0 :                 if ((err = wkbContains(&outBIT, geomWKB, &inWKB)) != MAL_SUCCEED) {
     868           0 :                         bat_iterator_end(&inBAT_iter);
     869           0 :                         BBPunfix(inBAT->batCacheid);
     870           0 :                         BBPunfix(outBAT->batCacheid);
     871           0 :                         return err;
     872             :                 }
     873           0 :                 if (BUNappend(outBAT, &outBIT, false) != GDK_SUCCEED) {
     874           0 :                         bat_iterator_end(&inBAT_iter);
     875           0 :                         BBPunfix(inBAT->batCacheid);
     876           0 :                         BBPunfix(outBAT->batCacheid);
     877           0 :                         throw(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     878             :                 }
     879             :         }
     880           0 :         bat_iterator_end(&inBAT_iter);
     881             : 
     882           0 :         BBPunfix(inBAT->batCacheid);
     883           0 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     884             : 
     885           0 :         return MAL_SUCCEED;
     886             : 
     887             : }
     888             : 
     889             : str
     890           8 : wkbContains_bat_geom(bat *outBAT_id, bat *inBAT_id, wkb **geomWKB)
     891             : {
     892             :         BAT *outBAT = NULL, *inBAT = NULL;
     893             :         BATiter inBAT_iter;
     894             :         BUN p = 0, q = 0;
     895             : 
     896             :         //get the descriptor of the BAT
     897           8 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     898           0 :                 throw(MAL, "batgeom.Contains", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     899             :         }
     900             : 
     901             :         //create a new BAT for the output
     902           8 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("bit"), BATcount(inBAT), TRANSIENT)) == NULL) {
     903           0 :                 BBPunfix(inBAT->batCacheid);
     904           0 :                 throw(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     905             :         }
     906             : 
     907             :         //iterator over the BATs
     908           8 :         inBAT_iter = bat_iterator(inBAT);
     909          25 :         BATloop(inBAT, p, q) {
     910             :                 str err = NULL;
     911             :                 bit outBIT;
     912             : 
     913          17 :                 wkb *inWKB = (wkb *) BUNtvar(inBAT_iter, p);
     914             : 
     915          17 :                 if ((err = wkbContains(&outBIT, &inWKB, geomWKB)) != MAL_SUCCEED) {
     916           0 :                         bat_iterator_end(&inBAT_iter);
     917           0 :                         BBPunfix(inBAT->batCacheid);
     918           0 :                         BBPunfix(outBAT->batCacheid);
     919           0 :                         return err;
     920             :                 }
     921          17 :                 if (BUNappend(outBAT, &outBIT, false) != GDK_SUCCEED) {
     922           0 :                         bat_iterator_end(&inBAT_iter);
     923           0 :                         BBPunfix(inBAT->batCacheid);
     924           0 :                         BBPunfix(outBAT->batCacheid);
     925           0 :                         throw(MAL, "batgeom.Contains", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     926             :                 }
     927             :         }
     928           8 :         bat_iterator_end(&inBAT_iter);
     929             : 
     930           8 :         BBPunfix(inBAT->batCacheid);
     931           8 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     932             : 
     933           8 :         return MAL_SUCCEED;
     934             : }
     935             : 
     936             : 
     937             : 
     938             : /*
     939             : str
     940             : wkbFromWKB_bat(bat *outBAT_id, bat *inBAT_id)
     941             : {
     942             :         BAT *outBAT = NULL, *inBAT = NULL;
     943             :         wkb **inWKB = NULL, *outWKB = NULL;
     944             :         BUN i;
     945             : 
     946             :         //get the descriptor of the BAT
     947             :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
     948             :                 throw(MAL, "batgeom.wkb", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     949             :         }
     950             : 
     951             :         //create a new BAT
     952             :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("wkb"), BATcount(inBAT))) == NULL) {
     953             :                 BBPunfix(inBAT->batCacheid);
     954             :                 throw(MAL, "batgeom.wkb", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     955             :         }
     956             : 
     957             :         //pointers to the first valid elements of the x and y BATS
     958             :         BATiter inBATi = bat_iterator(inBAT);
     959             :         inWKB = (wkb **) inBATi.base;
     960             :         for (i = 0; i < BATcount(inBAT); i++) {      //iterate over all valid elements
     961             :                 str err = NULL;
     962             :                 if ((err = wkbFromWKB(&outWKB, &inWKB[i])) != MAL_SUCCEED) {
     963             :                         BBPunfix(inBAT->batCacheid);
     964             :                         BBPunfix(outBAT->batCacheid);
     965             :                         return err;
     966             :                 }
     967             :                 if (BUNappend(outBAT, outWKB, false) != GDK_SUCCEED) {
     968             :                         BBPunfix(inBAT->batCacheid);
     969             :                         BBPunfix(outBAT->batCacheid);
     970             :                         GDKfree(outWKB);
     971             :                         throw(MAL, "batgeom.wkb", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     972             :                 }
     973             :                 GDKfree(outWKB);
     974             :                 outWKB = NULL;
     975             :         }
     976             :         bat_iterator_end(&inBATi);
     977             : 
     978             :         BBPunfix(inBAT->batCacheid);
     979             :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
     980             :         return MAL_SUCCEED;
     981             : 
     982             : }
     983             : */
     984             : 
     985             : /************************************/
     986             : /********* Multiple inputs **********/
     987             : /************************************/
     988             : str
     989           5 : wkbMakePoint_bat(bat *outBAT_id, bat *xBAT_id, bat *yBAT_id, bat *zBAT_id, bat *mBAT_id, int *zmFlag)
     990             : {
     991             :         BAT *outBAT = NULL, *xBAT = NULL, *yBAT = NULL, *zBAT = NULL, *mBAT = NULL;
     992             :         BATiter xBAT_iter, yBAT_iter, zBAT_iter, mBAT_iter;
     993             :         BUN i;
     994             :         str ret = MAL_SUCCEED;
     995             : 
     996           5 :         if (*zmFlag == 11)
     997           1 :                 throw(MAL, "batgeom.wkbMakePoint", SQLSTATE(38000) "POINTZM is not supported");
     998             : 
     999             :         //get the BATs
    1000           4 :         if ((xBAT = BATdescriptor(*xBAT_id)) == NULL || (yBAT = BATdescriptor(*yBAT_id)) == NULL || (*zmFlag == 10 && (zBAT = BATdescriptor(*zBAT_id)) == NULL)
    1001           4 :             || (*zmFlag == 1 && (mBAT = BATdescriptor(*mBAT_id)) == NULL)) {
    1002             : 
    1003           0 :                 ret = createException(MAL, "batgeom.wkbMakePoint", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1004           0 :                 goto clean;
    1005             :         }
    1006             :         //check if the BATs are aligned
    1007           4 :         if (xBAT->hseqbase != yBAT->hseqbase ||
    1008           4 :             BATcount(xBAT) != BATcount(yBAT) ||
    1009           4 :             (zBAT && (xBAT->hseqbase != zBAT->hseqbase || BATcount(xBAT) != BATcount(zBAT))) ||
    1010           1 :             (mBAT && (xBAT->hseqbase != mBAT->hseqbase || BATcount(xBAT) != BATcount(mBAT)))) {
    1011           0 :                 ret = createException(MAL, "batgeom.wkbMakePoint", SQLSTATE(38000) "Columns must be aligned");
    1012           0 :                 goto clean;
    1013             :         }
    1014             :         //create a new BAT for the output
    1015           4 :         if ((outBAT = COLnew(xBAT->hseqbase, ATOMindex("wkb"), BATcount(xBAT), TRANSIENT)) == NULL) {
    1016           0 :                 ret = createException(MAL, "batgeom.wkbMakePoint", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1017           0 :                 goto clean;
    1018             :         }
    1019             : 
    1020             :         //iterator over the BATs
    1021           4 :         xBAT_iter = bat_iterator(xBAT);
    1022           4 :         yBAT_iter = bat_iterator(yBAT);
    1023           4 :         if (zBAT)
    1024           1 :                 zBAT_iter = bat_iterator(zBAT);
    1025           4 :         if (mBAT)
    1026           1 :                 mBAT_iter = bat_iterator(mBAT);
    1027             : 
    1028          16 :         for (i = 0; i < BATcount(xBAT); i++) {
    1029          12 :                 wkb *pointWKB = NULL;
    1030             : 
    1031          12 :                 double x = *((double *) BUNtloc(xBAT_iter, i));
    1032          12 :                 double y = *((double *) BUNtloc(yBAT_iter, i));
    1033          12 :                 double z = 0.0;
    1034          12 :                 double m = 0.0;
    1035             : 
    1036          12 :                 if (zBAT)
    1037           3 :                         z = *((double *) BUNtloc(zBAT_iter, i));
    1038          12 :                 if (mBAT)
    1039           3 :                         m = *((double *) BUNtloc(mBAT_iter, i));
    1040             : 
    1041          12 :                 if ((ret = wkbMakePoint(&pointWKB, &x, &y, &z, &m, zmFlag)) != MAL_SUCCEED) {       //check
    1042             : 
    1043           0 :                         BBPreclaim(outBAT);
    1044           0 :                         goto bailout;
    1045             :                 }
    1046          12 :                 if (BUNappend(outBAT, pointWKB, false) != GDK_SUCCEED) {
    1047           0 :                         BBPreclaim(outBAT);
    1048           0 :                         GDKfree(pointWKB);
    1049           0 :                         ret = createException(MAL, "batgeom.WkbMakePoint", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1050           0 :                         goto bailout;
    1051             :                 }
    1052          12 :                 GDKfree(pointWKB);
    1053             :         }
    1054             : 
    1055           4 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1056             : 
    1057           4 :   bailout:
    1058           4 :         bat_iterator_end(&xBAT_iter);
    1059           4 :         bat_iterator_end(&yBAT_iter);
    1060           4 :         if (zBAT)
    1061           1 :                 bat_iterator_end(&zBAT_iter);
    1062           4 :         if (mBAT)
    1063           1 :                 bat_iterator_end(&mBAT_iter);
    1064           3 :   clean:
    1065           4 :         if (xBAT)
    1066           4 :                 BBPunfix(xBAT->batCacheid);
    1067           4 :         if (yBAT)
    1068           4 :                 BBPunfix(yBAT->batCacheid);
    1069           4 :         if (zBAT)
    1070           1 :                 BBPunfix(zBAT->batCacheid);
    1071           4 :         if (mBAT)
    1072           1 :                 BBPunfix(mBAT->batCacheid);
    1073             : 
    1074             :         return ret;
    1075             : }
    1076             : 
    1077             : 
    1078             : /* sets the srid of the geometry - BULK version*/
    1079             : str
    1080           0 : wkbSetSRID_bat(bat *outBAT_id, bat *inBAT_id, int *srid)
    1081             : {
    1082             :         BAT *outBAT = NULL, *inBAT = NULL;
    1083             :         BUN p = 0, q = 0;
    1084             :         BATiter inBAT_iter;
    1085             : 
    1086             :         //get the descriptor of the BAT
    1087           0 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
    1088           0 :                 throw(MAL, "batgeom.SetSRID", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1089             :         }
    1090             : 
    1091             :         //create a new BAT for the output
    1092           0 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("wkb"), BATcount(inBAT), TRANSIENT)) == NULL) {
    1093           0 :                 BBPunfix(inBAT->batCacheid);
    1094           0 :                 throw(MAL, "batgeom.SetSRID", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1095             :         }
    1096             : 
    1097             :         //iterator over the BATs
    1098           0 :         inBAT_iter = bat_iterator(inBAT);
    1099           0 :         BATloop(inBAT, p, q) {
    1100             :                 str err = NULL;
    1101           0 :                 wkb *outWKB = NULL;
    1102             : 
    1103           0 :                 wkb *inWKB = (wkb *) BUNtvar(inBAT_iter, p);
    1104             : 
    1105           0 :                 if ((err = wkbSetSRID(&outWKB, &inWKB, srid)) != MAL_SUCCEED) { //set SRID
    1106           0 :                         bat_iterator_end(&inBAT_iter);
    1107           0 :                         BBPunfix(inBAT->batCacheid);
    1108           0 :                         BBPunfix(outBAT->batCacheid);
    1109           0 :                         return err;
    1110             :                 }
    1111           0 :                 if (BUNappend(outBAT, outWKB, false) != GDK_SUCCEED) {
    1112           0 :                         bat_iterator_end(&inBAT_iter);
    1113           0 :                         BBPunfix(inBAT->batCacheid);
    1114           0 :                         BBPunfix(outBAT->batCacheid);
    1115           0 :                         GDKfree(outWKB);
    1116           0 :                         throw(MAL, "batgeom.SetSRID", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1117             :                 }
    1118           0 :                 GDKfree(outWKB);
    1119             :                 outWKB = NULL;
    1120             :         }
    1121           0 :         bat_iterator_end(&inBAT_iter);
    1122             : 
    1123           0 :         BBPunfix(inBAT->batCacheid);
    1124           0 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1125             : 
    1126           0 :         return MAL_SUCCEED;
    1127             : }
    1128             : 
    1129             : str
    1130           1 : wkbDistance_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id)
    1131             : {
    1132             :         BAT *outBAT = NULL, *aBAT = NULL, *bBAT = NULL;
    1133             :         BATiter aBAT_iter, bBAT_iter;
    1134             :         BUN i = 0;
    1135             :         str ret = MAL_SUCCEED;
    1136             : 
    1137             :         //get the BATs
    1138           1 :         if ((aBAT = BATdescriptor(*aBAT_id)) == NULL || (bBAT = BATdescriptor(*bBAT_id)) == NULL) {
    1139           0 :                 ret = createException(MAL, "batgeom.Distance", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1140           0 :                 goto clean;
    1141             :         }
    1142             :         //check if the BATs are aligned
    1143           1 :         if (aBAT->hseqbase != bBAT->hseqbase || BATcount(aBAT) != BATcount(bBAT)) {
    1144           0 :                 ret = createException(MAL, "batgeom.Distance", SQLSTATE(38000) "Columns must be aligned");
    1145           0 :                 goto clean;
    1146             :         }
    1147             :         //create a new BAT for the output
    1148           1 :         if ((outBAT = COLnew(aBAT->hseqbase, ATOMindex("dbl"), BATcount(aBAT), TRANSIENT)) == NULL) {
    1149           0 :                 ret = createException(MAL, "batgeom.Distance", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1150           0 :                 goto clean;
    1151             :         }
    1152             : 
    1153             :         //iterator over the BATs
    1154           1 :         aBAT_iter = bat_iterator(aBAT);
    1155           1 :         bBAT_iter = bat_iterator(bBAT);
    1156             : 
    1157           2 :         for (i = 0; i < BATcount(aBAT); i++) {
    1158           1 :                 double distanceVal = 0;
    1159             : 
    1160           1 :                 wkb *aWKB = (wkb *) BUNtvar(aBAT_iter, i);
    1161           1 :                 wkb *bWKB = (wkb *) BUNtvar(bBAT_iter, i);
    1162             : 
    1163           1 :                 if ((ret = wkbDistance(&distanceVal, &aWKB, &bWKB)) != MAL_SUCCEED) {       //check
    1164             : 
    1165           0 :                         BBPreclaim(outBAT);
    1166           0 :                         goto bailout;
    1167             :                 }
    1168           1 :                 if (BUNappend(outBAT, &distanceVal, false) != GDK_SUCCEED) {
    1169           0 :                         BBPreclaim(outBAT);
    1170           0 :                         ret = createException(MAL, "batgeom.Distance", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1171           0 :                         goto bailout;
    1172             :                 }
    1173             :         }
    1174             : 
    1175           1 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1176             : 
    1177           1 :   bailout:
    1178           1 :         bat_iterator_end(&aBAT_iter);
    1179           1 :         bat_iterator_end(&bBAT_iter);
    1180           1 :   clean:
    1181           1 :         if (aBAT)
    1182           1 :                 BBPunfix(aBAT->batCacheid);
    1183           1 :         if (bBAT)
    1184           1 :                 BBPunfix(bBAT->batCacheid);
    1185             : 
    1186           1 :         return ret;
    1187             : 
    1188             : }
    1189             : 
    1190             : str
    1191           0 : wkbDistance_geom_bat(bat *outBAT_id, wkb **geomWKB, bat *inBAT_id)
    1192             : {
    1193             :         BAT *outBAT = NULL, *inBAT = NULL;
    1194             :         BATiter inBAT_iter;
    1195             :         BUN p = 0, q = 0;
    1196             : 
    1197             :         //get the descriptor of the BAT
    1198           0 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
    1199           0 :                 throw(MAL, "batgeom.Distance", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1200             :         }
    1201             : 
    1202             :         //create a new BAT for the output
    1203           0 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("dbl"), BATcount(inBAT), TRANSIENT)) == NULL) {
    1204           0 :                 BBPunfix(inBAT->batCacheid);
    1205           0 :                 throw(MAL, "batgeom.Distance", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1206             :         }
    1207             : 
    1208             :         //iterator over the BAT
    1209           0 :         inBAT_iter = bat_iterator(inBAT);
    1210           0 :         BATloop(inBAT, p, q) {
    1211             :                 str err = NULL;
    1212           0 :                 double distanceVal = 0;
    1213             : 
    1214           0 :                 wkb *inWKB = (wkb *) BUNtvar(inBAT_iter, p);
    1215             : 
    1216           0 :                 if ((err = wkbDistance(&distanceVal, geomWKB, &inWKB)) != MAL_SUCCEED) {        //check
    1217           0 :                         bat_iterator_end(&inBAT_iter);
    1218           0 :                         BBPunfix(inBAT->batCacheid);
    1219           0 :                         BBPunfix(outBAT->batCacheid);
    1220           0 :                         return err;
    1221             :                 }
    1222           0 :                 if (BUNappend(outBAT, &distanceVal, false) != GDK_SUCCEED) {
    1223           0 :                         bat_iterator_end(&inBAT_iter);
    1224           0 :                         BBPunfix(inBAT->batCacheid);
    1225           0 :                         BBPunfix(outBAT->batCacheid);
    1226           0 :                         throw(MAL, "batgeom.Distance", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1227             :                 }
    1228             :         }
    1229           0 :         bat_iterator_end(&inBAT_iter);
    1230             : 
    1231           0 :         BBPunfix(inBAT->batCacheid);
    1232           0 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1233             : 
    1234           0 :         return MAL_SUCCEED;
    1235             : }
    1236             : 
    1237             : str
    1238           0 : wkbDistance_bat_geom(bat *outBAT_id, bat *inBAT_id, wkb **geomWKB)
    1239             : {
    1240           0 :         return wkbDistance_geom_bat(outBAT_id, geomWKB, inBAT_id);
    1241             : }
    1242             : 
    1243             : /**
    1244             :  * It filters the geometry in the second BAT with respect to the MBR of the geometry in the first BAT.
    1245             :  **/
    1246             : /*
    1247             : str
    1248             : wkbFilter_bat(bat *aBATfiltered_id, bat *bBATfiltered_id, bat *aBAT_id, bat *bBAT_id)
    1249             : {
    1250             :         BAT *aBATfiltered = NULL, *bBATfiltered = NULL, *aBAT = NULL, *bBAT = NULL;
    1251             :         wkb *aWKB = NULL, *bWKB = NULL;
    1252             :         bit outBIT;
    1253             :         BATiter aBAT_iter, bBAT_iter;
    1254             :         BUN i = 0;
    1255             :         int remainingElements = 0;
    1256             : 
    1257             :         //get the descriptor of the BAT
    1258             :         if ((aBAT = BATdescriptor(*aBAT_id)) == NULL) {
    1259             :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1260             :         }
    1261             :         if ((bBAT = BATdescriptor(*bBAT_id)) == NULL) {
    1262             :                 BBPunfix(aBAT->batCacheid);
    1263             :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1264             :         }
    1265             : 
    1266             :         if (aBAT->hseqbase != bBAT->hseqbase ||   //the idxs of the headers of the BATs are not the same
    1267             :             BATcount(aBAT) != BATcount(bBAT)) { //the number of valid elements in the BATs are not the same
    1268             :                 BBPunfix(aBAT->batCacheid);
    1269             :                 BBPunfix(bBAT->batCacheid);
    1270             :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(38000) "The arguments must have dense and aligned heads");
    1271             :         }
    1272             :         //create two new BATs for the output
    1273             :         if ((aBATfiltered = COLnew(aBAT->hseqbase, ATOMindex("wkb"), BATcount(aBAT), TRANSIENT)) == NULL) {
    1274             :                 BBPunfix(aBAT->batCacheid);
    1275             :                 BBPunfix(bBAT->batCacheid);
    1276             :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1277             :         }
    1278             :         if ((bBATfiltered = COLnew(bBAT->hseqbase, ATOMindex("wkb"), BATcount(bBAT), TRANSIENT)) == NULL) {
    1279             :                 BBPunfix(aBAT->batCacheid);
    1280             :                 BBPunfix(bBAT->batCacheid);
    1281             :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1282             :         }
    1283             : 
    1284             :         //iterator over the BATs
    1285             :         aBAT_iter = bat_iterator(aBAT);
    1286             :         bBAT_iter = bat_iterator(bBAT);
    1287             : 
    1288             :         for (i = 0; i < BATcount(aBAT); i++) {
    1289             :                 str err = NULL;
    1290             :                 aWKB = (wkb *) BUNtvar(aBAT_iter, i);
    1291             :                 bWKB = (wkb *) BUNtvar(bBAT_iter, i);
    1292             : 
    1293             :                 //check the containment of the MBRs
    1294             :                 if ((err = mbrOverlaps_wkb(&outBIT, &aWKB, &bWKB)) != MAL_SUCCEED) {
    1295             :                         bat_iterator_end(&aBAT_iter);
    1296             :                         bat_iterator_end(&bBAT_iter);
    1297             :                         BBPunfix(aBAT->batCacheid);
    1298             :                         BBPunfix(bBAT->batCacheid);
    1299             :                         BBPunfix(aBATfiltered->batCacheid);
    1300             :                         BBPunfix(bBATfiltered->batCacheid);
    1301             :                         return err;
    1302             :                 }
    1303             :                 if (outBIT) {
    1304             :                         if (BUNappend(aBATfiltered, aWKB, false) != GDK_SUCCEED ||
    1305             :                             BUNappend(bBATfiltered, bWKB, false) != GDK_SUCCEED) {
    1306             :                                 bat_iterator_end(&aBAT_iter);
    1307             :                                 bat_iterator_end(&bBAT_iter);
    1308             :                                 BBPunfix(aBAT->batCacheid);
    1309             :                                 BBPunfix(bBAT->batCacheid);
    1310             :                                 BBPunfix(aBATfiltered->batCacheid);
    1311             :                                 BBPunfix(bBATfiltered->batCacheid);
    1312             :                                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1313             :                         }
    1314             :                         remainingElements++;
    1315             :                 }
    1316             :         }
    1317             :         bat_iterator_end(&aBAT_iter);
    1318             :         bat_iterator_end(&bBAT_iter);
    1319             : 
    1320             :         BBPunfix(aBAT->batCacheid);
    1321             :         BBPunfix(bBAT->batCacheid);
    1322             :         BBPkeepref(*aBATfiltered_id = aBATfiltered->batCacheid);
    1323             :         BBPkeepref(*bBATfiltered_id = bBATfiltered->batCacheid);
    1324             : 
    1325             :         return MAL_SUCCEED;
    1326             : 
    1327             : 
    1328             : }
    1329             : */
    1330             : 
    1331             : /**
    1332             :  * It filters the geometry in the second BAT with respect to the MBR of the geometry in the first BAT.
    1333             :  **/
    1334             : str
    1335           0 : wkbFilter_geom_bat(bat *BATfiltered_id, wkb **geomWKB, bat *BAToriginal_id)
    1336             : {
    1337             :         BAT *BATfiltered = NULL, *BAToriginal = NULL;
    1338           0 :         wkb *WKBoriginal = NULL;
    1339             :         BATiter BAToriginal_iter;
    1340             :         BUN i = 0;
    1341             :         mbr *geomMBR;
    1342             :         int remainingElements = 0;
    1343             :         str err = NULL;
    1344             : 
    1345             :         //get the descriptor of the BAT
    1346           0 :         if ((BAToriginal = BATdescriptor(*BAToriginal_id)) == NULL) {
    1347           0 :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1348             :         }
    1349             : 
    1350             :         //create the new BAT
    1351           0 :         if ((BATfiltered = COLnew(BAToriginal->hseqbase, ATOMindex("wkb"), BATcount(BAToriginal), TRANSIENT)) == NULL) {
    1352           0 :                 BBPunfix(BAToriginal->batCacheid);
    1353           0 :                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1354             :         }
    1355             : 
    1356             :         //create the MBR of the geom
    1357           0 :         if ((err = wkbMBR(&geomMBR, geomWKB)) != MAL_SUCCEED) {
    1358           0 :                 BBPunfix(BAToriginal->batCacheid);
    1359           0 :                 BBPunfix(BATfiltered->batCacheid);
    1360           0 :                 return err;
    1361             :         }
    1362             : 
    1363             :         //iterator over the BAT
    1364           0 :         BAToriginal_iter = bat_iterator(BAToriginal);
    1365             : 
    1366           0 :         for (i = 0; i < BATcount(BAToriginal); i++) {
    1367             :                 str err = NULL;
    1368             :                 mbr *MBRoriginal;
    1369           0 :                 bit outBIT = 0;
    1370             : 
    1371           0 :                 WKBoriginal = (wkb *) BUNtvar(BAToriginal_iter, i);
    1372             : 
    1373             :                 //create the MBR for each geometry in the BAT
    1374           0 :                 if ((err = wkbMBR(&MBRoriginal, &WKBoriginal)) != MAL_SUCCEED) {
    1375           0 :                         bat_iterator_end(&BAToriginal_iter);
    1376           0 :                         BBPunfix(BAToriginal->batCacheid);
    1377           0 :                         BBPunfix(BATfiltered->batCacheid);
    1378           0 :                         GDKfree(geomMBR);
    1379           0 :                         return err;
    1380             :                 }
    1381             :                 //check the containment of the MBRs
    1382           0 :                 if ((err = mbrOverlaps(&outBIT, &geomMBR, &MBRoriginal)) != MAL_SUCCEED) {
    1383           0 :                         bat_iterator_end(&BAToriginal_iter);
    1384           0 :                         BBPunfix(BAToriginal->batCacheid);
    1385           0 :                         BBPunfix(BATfiltered->batCacheid);
    1386           0 :                         GDKfree(geomMBR);
    1387           0 :                         GDKfree(MBRoriginal);
    1388           0 :                         return err;
    1389             :                 }
    1390             : 
    1391           0 :                 if (outBIT) {
    1392           0 :                         if (BUNappend(BATfiltered, WKBoriginal, false) != GDK_SUCCEED) {
    1393           0 :                                 bat_iterator_end(&BAToriginal_iter);
    1394           0 :                                 BBPunfix(BAToriginal->batCacheid);
    1395           0 :                                 BBPunfix(BATfiltered->batCacheid);
    1396           0 :                                 GDKfree(geomMBR);
    1397           0 :                                 GDKfree(MBRoriginal);
    1398           0 :                                 throw(MAL, "batgeom.MBRfilter", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1399             :                         }
    1400             :                         remainingElements++;
    1401             :                 }
    1402             : 
    1403           0 :                 GDKfree(MBRoriginal);
    1404             :         }
    1405           0 :         bat_iterator_end(&BAToriginal_iter);
    1406             : 
    1407           0 :         GDKfree(geomMBR);
    1408           0 :         BBPunfix(BAToriginal->batCacheid);
    1409           0 :         BBPkeepref(*BATfiltered_id = BATfiltered->batCacheid);
    1410             : 
    1411           0 :         return MAL_SUCCEED;
    1412             : 
    1413             : }
    1414             : 
    1415             : str
    1416           0 : wkbFilter_bat_geom(bat *BATfiltered_id, bat *BAToriginal_id, wkb **geomWKB)
    1417             : {
    1418           0 :         return wkbFilter_geom_bat(BATfiltered_id, geomWKB, BAToriginal_id);
    1419             : }
    1420             : 
    1421             : /* MBR */
    1422             : 
    1423             : /* Creates the BAT with mbrs from the BAT with geometries. */
    1424             : str
    1425           6 : wkbMBR_bat(bat *outBAT_id, bat *inBAT_id)
    1426             : {
    1427             :         BAT *outBAT = NULL, *inBAT = NULL;
    1428           6 :         wkb *inWKB = NULL;
    1429           6 :         mbr *outMBR = NULL;
    1430             :         BUN p = 0, q = 0;
    1431             :         BATiter inBAT_iter;
    1432             : 
    1433             :         //get the descriptor of the BAT
    1434           6 :         if ((inBAT = BATdescriptor(*inBAT_id)) == NULL) {
    1435           0 :                 throw(MAL, "batgeom.mbr", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1436             :         }
    1437             : 
    1438             :         //create a new BAT for the output
    1439           6 :         if ((outBAT = COLnew(inBAT->hseqbase, ATOMindex("mbr"), BATcount(inBAT), TRANSIENT)) == NULL) {
    1440           0 :                 BBPunfix(inBAT->batCacheid);
    1441           0 :                 throw(MAL, "batgeom.mbr", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1442             :         }
    1443             : 
    1444             :         //iterator over the BAT
    1445           6 :         inBAT_iter = bat_iterator(inBAT);
    1446         146 :         BATloop(inBAT, p, q) {  //iterate over all valid elements
    1447             :                 str err = NULL;
    1448             : 
    1449         140 :                 inWKB = (wkb *) BUNtvar(inBAT_iter, p);
    1450         140 :                 if ((err = wkbMBR(&outMBR, &inWKB)) != MAL_SUCCEED) {
    1451           0 :                         bat_iterator_end(&inBAT_iter);
    1452           0 :                         BBPunfix(inBAT->batCacheid);
    1453           0 :                         BBPunfix(outBAT->batCacheid);
    1454           0 :                         return err;
    1455             :                 }
    1456         139 :                 if (BUNappend(outBAT, outMBR, false) != GDK_SUCCEED) {
    1457           0 :                         bat_iterator_end(&inBAT_iter);
    1458           0 :                         BBPunfix(inBAT->batCacheid);
    1459           0 :                         BBPunfix(outBAT->batCacheid);
    1460           0 :                         GDKfree(outMBR);
    1461           0 :                         throw(MAL, "batgeom.mbr", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1462             :                 }
    1463         140 :                 GDKfree(outMBR);
    1464         140 :                 outMBR = NULL;
    1465             :         }
    1466           6 :         bat_iterator_end(&inBAT_iter);
    1467             : 
    1468           6 :         BBPunfix(inBAT->batCacheid);
    1469           6 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1470           6 :         return MAL_SUCCEED;
    1471             : }
    1472             : 
    1473             : 
    1474             : str
    1475           4 : wkbCoordinateFromWKB_bat(bat *outBAT_id, bat *inBAT_id, int *coordinateIdx)
    1476             : {
    1477             :         str err = NULL;
    1478           4 :         int inBAT_mbr_id = 0;   //the id of the bat with the mbrs
    1479             : 
    1480           4 :         if ((err = wkbMBR_bat(&inBAT_mbr_id, inBAT_id)) != MAL_SUCCEED) {
    1481             :                 return err;
    1482             :         }
    1483             :         //call the bulk version of wkbCoordinateFromMBR
    1484           4 :         return wkbCoordinateFromMBR_bat(outBAT_id, &inBAT_mbr_id, coordinateIdx);
    1485             : }
    1486             : 
    1487             : str
    1488           0 : wkbMakeLine_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id)
    1489             : {
    1490             :         BAT *outBAT = NULL, *aBAT = NULL, *bBAT = NULL;
    1491             :         BATiter aBAT_iter, bBAT_iter;
    1492             :         BUN i;
    1493             : 
    1494             :         //get the BATs
    1495           0 :         aBAT = BATdescriptor(*aBAT_id);
    1496           0 :         bBAT = BATdescriptor(*bBAT_id);
    1497           0 :         if (aBAT == NULL || bBAT == NULL) {
    1498           0 :                 if (aBAT)
    1499           0 :                         BBPunfix(aBAT->batCacheid);
    1500           0 :                 if (bBAT)
    1501           0 :                         BBPunfix(bBAT->batCacheid);
    1502           0 :                 throw(MAL, "batgeom.MakeLine", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1503             :         }
    1504             :         //check if the BATs are aligned
    1505           0 :         if (aBAT->hseqbase != bBAT->hseqbase || BATcount(aBAT) != BATcount(bBAT)) {
    1506           0 :                 BBPunfix(aBAT->batCacheid);
    1507           0 :                 BBPunfix(bBAT->batCacheid);
    1508           0 :                 throw(MAL, "batgeom.MakeLine", SQLSTATE(38000) "Columns must be aligned");
    1509             :         }
    1510             :         //create a new BAT for the output
    1511           0 :         if ((outBAT = COLnew(aBAT->hseqbase, ATOMindex("wkb"), BATcount(aBAT), TRANSIENT)) == NULL) {
    1512           0 :                 BBPunfix(aBAT->batCacheid);
    1513           0 :                 BBPunfix(bBAT->batCacheid);
    1514           0 :                 throw(MAL, "batgeom.MakeLine", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1515             :         }
    1516             : 
    1517             :         //iterator over the BATs
    1518           0 :         aBAT_iter = bat_iterator(aBAT);
    1519           0 :         bBAT_iter = bat_iterator(bBAT);
    1520             : 
    1521           0 :         for (i = 0; i < BATcount(aBAT); i++) {
    1522             :                 str err = NULL;
    1523           0 :                 wkb *aWKB = NULL, *bWKB = NULL, *outWKB = NULL;
    1524             : 
    1525           0 :                 aWKB = (wkb *) BUNtvar(aBAT_iter, i);
    1526           0 :                 bWKB = (wkb *) BUNtvar(bBAT_iter, i);
    1527             : 
    1528           0 :                 if ((err = wkbMakeLine(&outWKB, &aWKB, &bWKB)) != MAL_SUCCEED) {    //check
    1529           0 :                         bat_iterator_end(&aBAT_iter);
    1530           0 :                         bat_iterator_end(&bBAT_iter);
    1531           0 :                         BBPunfix(outBAT->batCacheid);
    1532           0 :                         BBPunfix(aBAT->batCacheid);
    1533           0 :                         BBPunfix(bBAT->batCacheid);
    1534           0 :                         return err;
    1535             :                 }
    1536           0 :                 if (BUNappend(outBAT, outWKB, false) != GDK_SUCCEED) {
    1537           0 :                         bat_iterator_end(&aBAT_iter);
    1538           0 :                         bat_iterator_end(&bBAT_iter);
    1539           0 :                         BBPunfix(outBAT->batCacheid);
    1540           0 :                         BBPunfix(aBAT->batCacheid);
    1541           0 :                         BBPunfix(bBAT->batCacheid);
    1542           0 :                         GDKfree(outWKB);
    1543           0 :                         throw(MAL, "batgeom.MakeLine", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1544             :                 }
    1545           0 :                 GDKfree(outWKB);
    1546             :                 outWKB = NULL;
    1547             :         }
    1548           0 :         bat_iterator_end(&aBAT_iter);
    1549           0 :         bat_iterator_end(&bBAT_iter);
    1550             : 
    1551           0 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1552           0 :         BBPunfix(aBAT->batCacheid);
    1553           0 :         BBPunfix(bBAT->batCacheid);
    1554             : 
    1555           0 :         return MAL_SUCCEED;
    1556             : }
    1557             : 
    1558             : str
    1559           0 : wkbUnion_bat(bat *outBAT_id, bat *aBAT_id, bat *bBAT_id)
    1560             : {
    1561             :         BAT *outBAT = NULL, *aBAT = NULL, *bBAT = NULL;
    1562             :         BATiter aBAT_iter, bBAT_iter;
    1563             :         BUN i;
    1564             : 
    1565             :         //get the BATs
    1566           0 :         aBAT = BATdescriptor(*aBAT_id);
    1567           0 :         bBAT = BATdescriptor(*bBAT_id);
    1568           0 :         if (aBAT == NULL || bBAT == NULL) {
    1569           0 :                 if (aBAT)
    1570           0 :                         BBPunfix(aBAT->batCacheid);
    1571           0 :                 if (bBAT)
    1572           0 :                         BBPunfix(bBAT->batCacheid);
    1573           0 :                 throw(MAL, "batgeom.Union", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
    1574             :         }
    1575             :         //check if the BATs are aligned
    1576           0 :         if (aBAT->hseqbase != bBAT->hseqbase || BATcount(aBAT) != BATcount(bBAT)) {
    1577           0 :                 BBPunfix(aBAT->batCacheid);
    1578           0 :                 BBPunfix(bBAT->batCacheid);
    1579           0 :                 throw(MAL, "batgeom.Union", SQLSTATE(38000) "Columns must be aligned");
    1580             :         }
    1581             :         //create a new BAT for the output
    1582           0 :         if ((outBAT = COLnew(aBAT->hseqbase, ATOMindex("wkb"), BATcount(aBAT), TRANSIENT)) == NULL) {
    1583           0 :                 BBPunfix(aBAT->batCacheid);
    1584           0 :                 BBPunfix(bBAT->batCacheid);
    1585           0 :                 throw(MAL, "batgeom.Union", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1586             :         }
    1587             : 
    1588             :         //iterator over the BATs
    1589           0 :         aBAT_iter = bat_iterator(aBAT);
    1590           0 :         bBAT_iter = bat_iterator(bBAT);
    1591             : 
    1592           0 :         for (i = 0; i < BATcount(aBAT); i++) {
    1593             :                 str err = NULL;
    1594           0 :                 wkb *aWKB = NULL, *bWKB = NULL, *outWKB = NULL;
    1595             : 
    1596           0 :                 aWKB = (wkb *) BUNtvar(aBAT_iter, i);
    1597           0 :                 bWKB = (wkb *) BUNtvar(bBAT_iter, i);
    1598             : 
    1599           0 :                 if ((err = wkbUnion(&outWKB, &aWKB, &bWKB)) != MAL_SUCCEED) {       //check
    1600           0 :                         bat_iterator_end(&aBAT_iter);
    1601           0 :                         bat_iterator_end(&bBAT_iter);
    1602           0 :                         BBPunfix(outBAT->batCacheid);
    1603           0 :                         BBPunfix(aBAT->batCacheid);
    1604           0 :                         BBPunfix(bBAT->batCacheid);
    1605           0 :                         return err;
    1606             :                 }
    1607           0 :                 if (BUNappend(outBAT, outWKB, false) != GDK_SUCCEED) {
    1608           0 :                         bat_iterator_end(&aBAT_iter);
    1609           0 :                         bat_iterator_end(&bBAT_iter);
    1610           0 :                         BBPunfix(outBAT->batCacheid);
    1611           0 :                         BBPunfix(aBAT->batCacheid);
    1612           0 :                         BBPunfix(bBAT->batCacheid);
    1613           0 :                         GDKfree(outWKB);
    1614           0 :                         throw(MAL, "batgeom.Union", SQLSTATE(HY013) MAL_MALLOC_FAIL);
    1615             :                 }
    1616           0 :                 GDKfree(outWKB);
    1617             :                 outWKB = NULL;
    1618             :         }
    1619           0 :         bat_iterator_end(&aBAT_iter);
    1620           0 :         bat_iterator_end(&bBAT_iter);
    1621             : 
    1622           0 :         BBPkeepref(*outBAT_id = outBAT->batCacheid);
    1623           0 :         BBPunfix(aBAT->batCacheid);
    1624           0 :         BBPunfix(bBAT->batCacheid);
    1625             : 
    1626           0 :         return MAL_SUCCEED;
    1627             : }

Generated by: LCOV version 1.14