]> granicus.if.org Git - postgis/commitdiff
Resolved a bunch of memory issues related to use of SPI that have been bugging me...
authorBborie Park <bkpark at ucdavis.edu>
Tue, 6 Dec 2011 06:06:28 +0000 (06:06 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Tue, 6 Dec 2011 06:06:28 +0000 (06:06 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@8306 b70326c6-7e19-0410-871a-916f4a2858ee

raster/rt_pg/rt_pg.c

index 6117c002377872fd42651bb255edb5f2b2ed7dd6..712301a0dd68b5eca62e91c1a38efb5d39c6cbb6 100644 (file)
@@ -499,7 +499,7 @@ rtpg_getSRTextSPI(int srid)
        /* execute query */
        snprintf(sql, len, "SELECT srtext FROM spatial_ref_sys WHERE srid = %d LIMIT 1", srid);
        spi_result = SPI_execute(sql, TRUE, 0);
-       pfree(sql);
+       SPI_pfree(sql);
        if (spi_result != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
                elog(ERROR, "rtpg_getSRTextSPI: Cannot find SRID (%d) in spatial_ref_sys", srid);
                if (SPI_tuptable) SPI_freetuptable(tuptable);
@@ -519,18 +519,21 @@ rtpg_getSRTextSPI(int srid)
                return NULL;
        }
 
-       SPI_freetuptable(tuptable);
-       SPI_finish();
-
-       len = strlen(tmp);
-       srs = (char *) palloc(sizeof(char) * (len + 1));
+       len = strlen(tmp) + 1;
+       srs = SPI_palloc(sizeof(char) * len);
        if (NULL == srs) {
                elog(ERROR, "rtpg_getSRTextSPI: Unable to allocate memory for srtext\n");
+               pfree(tmp);
+               if (SPI_tuptable) SPI_freetuptable(tuptable);
+               SPI_finish();
                return NULL;
        }
-       srs = strncpy(srs, tmp, len + 1);
+       strncpy(srs, tmp, len);
        pfree(tmp);
 
+       if (SPI_tuptable) SPI_freetuptable(tuptable);
+       SPI_finish();
+
        return srs;
 }
 
@@ -3712,7 +3715,7 @@ Datum RASTER_summaryStatsCoverage(PG_FUNCTION_ARGS)
                NULL, NULL,
                TRUE, 0
        );
-       pfree(sql);
+       SPI_pfree(sql);
 
        /* process resultset */
        SPI_cursor_fetch(portal, TRUE, 1);
@@ -3804,7 +3807,7 @@ Datum RASTER_summaryStatsCoverage(PG_FUNCTION_ARGS)
                /* initialize rtn */
                if (stats->count > 0) {
                        if (NULL == rtn) {
-                               rtn = (rt_bandstats) palloc(sizeof(struct rt_bandstats_t));
+                               rtn = (rt_bandstats) SPI_palloc(sizeof(struct rt_bandstats_t));
                                if (NULL == rtn) {
                                        elog(ERROR, "RASTER_summaryStatsCoverage: Unable to allocate memory for summary stats of coverage\n");
 
@@ -4376,7 +4379,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                snprintf(sql, len, "SELECT min, max FROM _st_summarystats('%s','%s',%d,%d::boolean,%f)", tablename, colname, bandindex, (exclude_nodata_value ? 1 : 0), sample);
                POSTGIS_RT_DEBUGF(3, "RASTER_histogramCoverage: %s", sql);
                spi_result = SPI_execute(sql, TRUE, 0);
-               pfree(sql);
+               SPI_pfree(sql);
                if (spi_result != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
                        elog(ERROR, "RASTER_histogramCoverage: Could not get summary stats of coverage");
 
@@ -4463,7 +4466,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                SPI_cursor_close(portal);
                                SPI_finish();
 
-                               if (NULL != covhist) free(covhist);
+                               if (NULL != covhist) pfree(covhist);
                                if (bin_width_count) pfree(bin_width);
 
                                SRF_RETURN_DONE(funcctx);
@@ -4483,7 +4486,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                SPI_cursor_close(portal);
                                SPI_finish();
 
-                               if (NULL != covhist) free(covhist);
+                               if (NULL != covhist) pfree(covhist);
                                if (bin_width_count) pfree(bin_width);
 
                                SRF_RETURN_DONE(funcctx);
@@ -4499,7 +4502,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                SPI_finish();
 
                                rt_raster_destroy(raster);
-                               if (NULL != covhist) free(covhist);
+                               if (NULL != covhist) pfree(covhist);
                                if (bin_width_count) pfree(bin_width);
 
                                SRF_RETURN_DONE(funcctx);
@@ -4515,7 +4518,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                SPI_finish();
 
                                rt_raster_destroy(raster);
-                               if (NULL != covhist) free(covhist);
+                               if (NULL != covhist) pfree(covhist);
                                if (bin_width_count) pfree(bin_width);
 
                                SRF_RETURN_DONE(funcctx);
@@ -4534,7 +4537,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                SPI_cursor_close(portal);
                                SPI_finish();
 
-                               if (NULL != covhist) free(covhist);
+                               if (NULL != covhist) pfree(covhist);
                                if (bin_width_count) pfree(bin_width);
 
                                SRF_RETURN_DONE(funcctx);
@@ -4551,7 +4554,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
                                        SPI_cursor_close(portal);
                                        SPI_finish();
 
-                                       if (NULL != covhist) free(covhist);
+                                       if (NULL != covhist) pfree(covhist);
                                        if (bin_width_count) pfree(bin_width);
 
                                        SRF_RETURN_DONE(funcctx);
@@ -4561,22 +4564,16 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
 
                                /* coverage histogram */
                                if (NULL == covhist) {
-                                       /*
-                                               dustymugs 2011-08-25
-                                               covhist is initialized using malloc instead of palloc due to
-                                                       strange memory issues where covvcnts is corrupted in
-                                                       subsequent calls of SRF
-                                       */
-                                       covhist = (rt_histogram) malloc(sizeof(struct rt_histogram_t) * count);
+                                       covhist = (rt_histogram) SPI_palloc(sizeof(struct rt_histogram_t) * count);
                                        if (NULL == covhist) {
                                                elog(ERROR, "RASTER_histogramCoverage: Unable to allocate memory for histogram of coverage");
 
+                                               pfree(hist);
                                                if (SPI_tuptable) SPI_freetuptable(tuptable);
                                                SPI_cursor_close(portal);
                                                SPI_finish();
 
                                                if (bin_width_count) pfree(bin_width);
-                                               pfree(hist);
 
                                                SRF_RETURN_DONE(funcctx);
                                        }
@@ -4680,7 +4677,7 @@ Datum RASTER_histogramCoverage(PG_FUNCTION_ARGS)
        }
        /* do when there is no more left */
        else {
-               free(covhist2);
+               pfree(covhist2);
                SRF_RETURN_DONE(funcctx);
        }
 }
@@ -5124,7 +5121,7 @@ Datum RASTER_quantileCoverage(PG_FUNCTION_ARGS)
                snprintf(sql, len, "SELECT count FROM _st_summarystats('%s','%s',%d,%d::boolean,%f)", tablename, colname, bandindex, (exclude_nodata_value ? 1 : 0), sample);
                POSTGIS_RT_DEBUGF(3, "stats sql:  %s", sql);
                spi_result = SPI_execute(sql, TRUE, 0);
-               pfree(sql);
+               SPI_pfree(sql);
                if (spi_result != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
                        elog(ERROR, "RASTER_quantileCoverage: Could not get summary stats of coverage");
 
@@ -5266,26 +5263,21 @@ Datum RASTER_quantileCoverage(PG_FUNCTION_ARGS)
                        SPI_cursor_fetch(portal, TRUE, 1);
                }
 
+               covquant2 = SPI_palloc(sizeof(struct rt_quantile_t) * count);
+               for (i = 0; i < count; i++) {
+                       covquant2[i].quantile = covquant[i].quantile;
+                       covquant2[i].value = covquant[i].value;
+               }
+
+               if (NULL != covquant) pfree(covquant);
+               quantile_llist_destroy(&qlls, qlls_count);
+
                if (SPI_tuptable) SPI_freetuptable(tuptable);
                SPI_cursor_close(portal);
                SPI_finish();
 
-               quantile_llist_destroy(&qlls, qlls_count);
                if (quantiles_count) pfree(quantiles);
 
-               /*
-                       dustymugs 2011-08-23
-                       covquant2 is initialized using malloc instead of palloc due to
-                               strange memory issues where covvcnts is corrupted in
-                               subsequent calls of SRF
-               */
-               covquant2 = malloc(sizeof(struct rt_quantile_t) * count);
-               for (i = 0; i < count; i++) {
-                       covquant2[i].quantile = covquant[i].quantile;
-                       covquant2[i].value = covquant[i].value;
-               }
-               pfree(covquant);
-
                POSTGIS_RT_DEBUGF(3, "%d quantiles returned", count);
 
                /* Store needed information */
@@ -5349,7 +5341,7 @@ Datum RASTER_quantileCoverage(PG_FUNCTION_ARGS)
        /* do when there is no more left */
        else {
                POSTGIS_RT_DEBUG(3, "done");
-               free(covquant2);
+               pfree(covquant2);
                SRF_RETURN_DONE(funcctx);
        }
 }
@@ -5751,7 +5743,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                        NULL, NULL,
                        TRUE, 0
                );
-               pfree(sql);
+               SPI_pfree(sql);
 
                /* process resultset */
                SPI_cursor_fetch(portal, TRUE, 1);
@@ -5768,7 +5760,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                                SPI_cursor_close(portal);
                                SPI_finish();
 
-                               if (NULL != covvcnts) free(covvcnts);
+                               if (NULL != covvcnts) pfree(covvcnts);
                                if (search_values_count) pfree(search_values);
 
                                SRF_RETURN_DONE(funcctx);
@@ -5788,7 +5780,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                                SPI_cursor_close(portal);
                                SPI_finish();
 
-                               if (NULL != covvcnts) free(covvcnts);
+                               if (NULL != covvcnts) pfree(covvcnts);
                                if (search_values_count) pfree(search_values);
 
                                SRF_RETURN_DONE(funcctx);
@@ -5804,7 +5796,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                                SPI_finish();
 
                                rt_raster_destroy(raster);
-                               if (NULL != covvcnts) free(covvcnts);
+                               if (NULL != covvcnts) pfree(covvcnts);
                                if (search_values_count) pfree(search_values);
 
                                SRF_RETURN_DONE(funcctx);
@@ -5820,7 +5812,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                                SPI_finish();
 
                                rt_raster_destroy(raster);
-                               if (NULL != covvcnts) free(covvcnts);
+                               if (NULL != covvcnts) pfree(covvcnts);
                                if (search_values_count) pfree(search_values);
 
                                SRF_RETURN_DONE(funcctx);
@@ -5832,28 +5824,31 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                        rt_raster_destroy(raster);
                        if (NULL == vcnts || !count) {
                                elog(NOTICE, "Unable to count the values for band at index %d", bandindex);
+
+                               pfree(vcnts);
+                               if (SPI_tuptable) SPI_freetuptable(tuptable);
+                               SPI_cursor_close(portal);
+                               SPI_finish();
+
+                               if (NULL != covvcnts) free(covvcnts);
+                               if (search_values_count) pfree(search_values);
+
                                SRF_RETURN_DONE(funcctx);
                        }
 
                        POSTGIS_RT_DEBUGF(3, "%d value counts returned", count);
 
                        if (NULL == covvcnts) {
-                               /*
-                                       dustymugs 2011-08-23
-                                       covvcnts is initialized using malloc instead of palloc due to
-                                               strange memory issues where covvcnts is corrupted in
-                                               subsequent calls of SRF
-                               */
-                               covvcnts = (rt_valuecount) malloc(sizeof(struct rt_valuecount_t) * count);
+                               covvcnts = (rt_valuecount) SPI_palloc(sizeof(struct rt_valuecount_t) * count);
                                if (NULL == covvcnts) {
                                        elog(ERROR, "RASTER_valueCountCoverage: Unable to allocate memory for value counts of coverage");
 
+                                       pfree(vcnts);
                                        if (SPI_tuptable) SPI_freetuptable(tuptable);
                                        SPI_cursor_close(portal);
                                        SPI_finish();
 
                                        if (search_values_count) pfree(search_values);
-                                       pfree(vcnts);
 
                                        SRF_RETURN_DONE(funcctx);
                                }
@@ -5882,17 +5877,17 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
                                        }
                                        else {
                                                covcount++;
-                                               covvcnts = realloc(covvcnts, sizeof(struct rt_valuecount_t) * covcount);
+                                               covvcnts = SPI_repalloc(covvcnts, sizeof(struct rt_valuecount_t) * covcount);
                                                if (NULL == covvcnts) {
                                                        elog(ERROR, "RASTER_valueCountCoverage: Unable to change allocated memory for value counts of coverage");
 
+                                                       pfree(vcnts);
                                                        if (SPI_tuptable) SPI_freetuptable(tuptable);
                                                        SPI_cursor_close(portal);
                                                        SPI_finish();
 
                                                        if (search_values_count) pfree(search_values);
                                                        if (NULL != covvcnts) free(covvcnts);
-                                                       pfree(vcnts);
 
                                                        SRF_RETURN_DONE(funcctx);
                                                }
@@ -5984,7 +5979,7 @@ Datum RASTER_valueCountCoverage(PG_FUNCTION_ARGS) {
        }
        /* do when there is no more left */
        else {
-               free(covvcnts2);
+               pfree(covvcnts2);
                SRF_RETURN_DONE(funcctx);
        }
 }
@@ -8620,10 +8615,13 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                        sql = (char *) palloc(len + 1);
                                        if (sql == NULL) {
                                                elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for expression parameter %d", exprpos[i]);
-                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                               rt_raster_destroy(raster);
+
                                                for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                SPI_finish();
+
+                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                               rt_raster_destroy(raster);
+
                                                PG_RETURN_NULL();
                                        }
 
@@ -8640,13 +8638,12 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                if (argtype == NULL) {
                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for prepared plan argtypes of expression parameter %d", exprpos[i]);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
-
+                                                       pfree(sql);
                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                        SPI_finish();
 
-                                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
                                                        PG_RETURN_NULL();
                                                }
@@ -8656,14 +8653,14 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                if (spiplan[i] == NULL) {
                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to create prepared plan of expression parameter %d", exprpos[i]);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
-
+                                                       pfree(sql);
+                                                       pfree(argtype);
                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                        SPI_finish();
 
-                                                       pfree(sql);
-                                                       pfree(argtype);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
+
 
                                                        PG_RETURN_NULL();
                                                }
@@ -8676,13 +8673,12 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to evaluate expression parameter %d", exprpos[i]);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
-
+                                                       pfree(sql);
                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                        SPI_finish();
 
-                                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
                                                        PG_RETURN_NULL();
                                                }
@@ -8696,14 +8692,13 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to get result of expression parameter %d", exprpos[i]);
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
-
+                                                       pfree(sql);
                                                        if (SPI_tuptable) SPI_freetuptable(tuptable);
                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                        SPI_finish();
 
-                                                       pfree(sql);
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
 
                                                        PG_RETURN_NULL();
                                                }
@@ -8827,14 +8822,14 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                if (err < 0) {
                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to get pixel of %s raster", (i < 1 ? "FIRST" : "SECOND"));
 
-                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                       rt_raster_destroy(raster);
-
                                                        if (calltype == TEXTOID) {
                                                                for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                                SPI_finish();
                                                        }
 
+                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                       rt_raster_destroy(raster);
+
                                                        PG_RETURN_NULL();
                                                }
 
@@ -8895,12 +8890,12 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                                if (values == NULL) {
                                                                        elog(ERROR, "RASTER_mapAlgebra2: Unable to allocate memory for value parameters of prepared statement %d", i);
 
-                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                                       rt_raster_destroy(raster);
-
                                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                                        SPI_finish();
 
+                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                                       rt_raster_destroy(raster);
+
                                                                        PG_RETURN_NULL();
                                                                }
 
@@ -8910,12 +8905,12 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
 
                                                                        pfree(values);
 
-                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                                       rt_raster_destroy(raster);
-
                                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                                        SPI_finish();
 
+                                                                       for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                                       rt_raster_destroy(raster);
+
                                                                        PG_RETURN_NULL();
                                                                }
                                                                memset(nulls, FALSE, argcount[i]);
@@ -8954,12 +8949,12 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                        if (err != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
                                                                elog(ERROR, "RASTER_mapAlgebra2: Unexpected error when running prepared statement %d", i);
 
-                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                               rt_raster_destroy(raster);
-
                                                                for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                                SPI_finish();
 
+                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                               rt_raster_destroy(raster);
+
                                                                PG_RETURN_NULL();
                                                        }
 
@@ -8972,13 +8967,13 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                                        if (SPI_result == SPI_ERROR_NOATTRIBUTE) {
                                                                elog(ERROR, "RASTER_mapAlgebra2: Unable to get result of prepared statement %d", i);
 
-                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                                               rt_raster_destroy(raster);
-
                                                                if (SPI_tuptable) SPI_freetuptable(tuptable);
                                                                for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                                SPI_finish();
 
+                                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                                               rt_raster_destroy(raster);
+
                                                                PG_RETURN_NULL();
                                                        }
 
@@ -9025,14 +9020,14 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS)
                                        if (rt_band_set_pixel(band, x, y, pixel) < 0) {
                                                elog(ERROR, "RASTER_mapAlgebra2: Unable to set pixel value of output raster");
 
-                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
-                                               rt_raster_destroy(raster);
-
                                                if (calltype == TEXTOID) {
                                                        for (k = 0; k < spicount; k++) SPI_freeplan(spiplan[k]);
                                                        SPI_finish();
                                                }
 
+                                               for (k = 0; k < set_count; k++) rt_raster_destroy(_rast[k]);
+                                               rt_raster_destroy(raster);
+
                                                PG_RETURN_NULL();
                                        }
                                }