found++, tmp += oldlen;
length = strlen(str) + found * (newlen - oldlen);
- if ( (result = (char *)palloc(length+1)) == NULL) {
+
+ /**
+ * From: http://www.postgresql.org/docs/8.4/static/spi-memory.html
+ * "(...) if your procedure needs to return an object in allocated memory
+ * (such as a value of a pass-by-reference data type), you cannot allocate
+ * that memory using palloc, at least not while you are connected to SPI.
+ * If you try, the object will be deallocated by SPI_finish, and your
+ * procedure will not work reliably. To solve this problem, use SPI_palloc to
+ * allocate memory for your return object. SPI_palloc allocates memory in the
+ * "upper executor context", that is, the memory context that was current
+ * when SPI_connect was called, which is precisely the right context for a
+ * value returned from your procedure."
+ *
+ * So, we use SPI_palloc for allocating memory.
+ */
+ if ( (result = (char *)SPI_palloc(length+1)) == NULL) {
fprintf(stderr, "Not enough memory\n");
found = -1;
} else {
PG_FUNCTION_INFO_V1(RASTER_out);
Datum RASTER_out(PG_FUNCTION_ARGS)
{
- rt_pgraster *pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ rt_pgraster *pgraster = NULL;
rt_raster raster = NULL;
uint32_t hexwkbsize = 0;
char *hexwkb = NULL;
- rt_context ctx = get_rt_context(fcinfo);
+ rt_context ctx = NULL;
+
+ pgraster = (rt_pgraster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ ctx = get_rt_context(fcinfo);
raster = rt_raster_deserialize(ctx, pgraster);
if ( ! raster ) {
POSTGIS_RT_DEBUG(2, "RASTER_mapAlgebra: Starting...");
/* Check raster */
- if (PG_ARGISNULL(0)) {
- elog(WARNING, "RASTER_mapAlgebra: Raster is NULL. Returning NULL");
+ if (PG_ARGISNULL(0))
+ {
+ elog(NOTICE, "Raster is NULL. Returning NULL");
PG_RETURN_NULL();
}
/* Deserialize raster */
pgraster = (rt_pgraster *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0));
ctx = get_rt_context(fcinfo);
- if (!ctx)
+ if (NULL == ctx)
{
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("RASTER_mapAlgebra: Could not deserialize raster")));
+ elog(ERROR, "RASTER_mapAlgebra: Could not get memory context. Returning"
+ " NULL");
PG_RETURN_NULL();
}
raster = rt_raster_deserialize(ctx, pgraster);
- if (!raster)
+ if (NULL == raster)
{
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("RASTER_mapAlgebra: Could not deserialize raster")));
+ elog(ERROR, "RASTER_mapAlgebra: Could not deserialize raster");
rt_context_destroy(ctx);
PG_RETURN_NULL();
}
newrast = rt_raster_new(ctx, width, height);
- if ( ! newrast ) {
- elog(ERROR, "RASTER_mapAlgebra: Could not create a new raster");
+ if ( NULL == newrast )
+ {
+ elog(ERROR, "RASTER_mapAlgebra: Could not create a new raster. "
+ "Returning NULL");
rt_raster_destroy(ctx, raster);
rt_context_destroy(ctx);
PG_RETURN_NULL();
* If this new raster is empty (width = 0 OR height = 0) then there is
* nothing to compute and we return it right now
**/
- if (rt_raster_is_empty(ctx, newrast)) {
- elog(WARNING, "RASTER_mapAlgebra: Raster is empty. Returning an empty raster");
+ if (rt_raster_is_empty(ctx, newrast))
+ {
+ elog(NOTICE, "Raster is empty. Returning an empty raster");
+ rt_raster_destroy(ctx, raster);
+
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster) PG_RETURN_NULL();
+ if (NULL == pgraster) {
+ rt_raster_destroy(ctx, newrast);
+ rt_context_destroy(ctx);
+ elog(ERROR, "RASTER_mapAlgebra: Could not serialize raster. "
+ "Returning NULL");
+ PG_RETURN_NULL();
+ }
SET_VARSIZE(pgraster, pgraster->size);
+ rt_raster_destroy(ctx, newrast);
- rt_raster_destroy(ctx, raster);
- rt_context_destroy(ctx);
+ // XXX jorgearevalo: Dont destroy context. I think we need it here...
PG_RETURN_POINTER(pgraster);
}
* Check if the raster has the required band. Otherwise, return a raster
* without band
**/
- if (rt_raster_has_no_band(ctx, raster, nband)) {
- elog(WARNING, "RASTER_mapAlgebra: Raster do not have the required band. "
- "Returning a raster without a band");
+ if (rt_raster_has_no_band(ctx, raster, nband))
+ {
+ elog(NOTICE, "Raster do not have the required band. Returning a raster "
+ "without a band");
+ rt_raster_destroy(ctx, raster);
+
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster) PG_RETURN_NULL();
+ if (NULL == pgraster) {
+ rt_raster_destroy(ctx, newrast);
+ rt_context_destroy(ctx);
+ elog(ERROR, "RASTER_mapAlgebra: Could not serialize raster. "
+ "Returning NULL");
+ PG_RETURN_NULL();
+ }
SET_VARSIZE(pgraster, pgraster->size);
-
- rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
+
PG_RETURN_POINTER(pgraster);
}
/* Get the raster band */
band = rt_raster_get_band(ctx, raster, nband - 1);
- if ( ! band ) {
- elog(ERROR, "RASTER_mapAlgebra: Could not get band %d for raster", nband);
+ if ( NULL == band )
+ {
+ elog(NOTICE, "Could not get the required band. Returning a raster "
+ "without a band");
rt_raster_destroy(ctx, raster);
+
+ pgraster = rt_raster_serialize(ctx, newrast);
+ if (NULL == pgraster) {
+ rt_raster_destroy(ctx,newrast);
+ rt_context_destroy(ctx);
+ elog(ERROR, "RASTER_mapAlgebra: Could not serialize raster. "
+ "Returning NULL");
+ PG_RETURN_NULL();
+ }
+
+ SET_VARSIZE(pgraster, pgraster->size);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
- PG_RETURN_NULL();
+
+ PG_RETURN_POINTER(pgraster);
}
/* Check for nodata value */
/**
* Set the new pixeltype
**/
- if (PG_ARGISNULL(4)) {
+ if (PG_ARGISNULL(4))
+ {
newpixeltype = rt_band_get_pixtype(ctx, band);
}
- else {
+ else
+ {
strFromText = text_to_cstring(PG_GETARG_TEXT_P(4));
newpixeltype = rt_pixtype_index_from_name(ctx,strFromText);
lwfree(strFromText);
newpixeltype = rt_band_get_pixtype(ctx, band);
}
- if (newpixeltype == PT_END) {
- elog(ERROR, "RASTER_mapAlgebra: Invalid pixeltype. Aborting");
+ if (newpixeltype == PT_END)
+ {
+ elog(ERROR, "RASTER_mapAlgebra: Invalid pixeltype. Returning NULL");
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
PG_RETURN_NULL();
/* Construct expression for raster values */
- if (!PG_ARGISNULL(2)) {
+ if (!PG_ARGISNULL(2))
+ {
expression = text_to_cstring(PG_GETARG_TEXT_P(2));
len = strlen("SELECT ") + strlen(expression);
initexpr = (char *)palloc(len + 1);
* value. Then, we can initialize the raster with this value and skip the
* computation of nodata values one by one in the main computing loop
**/
- if (!PG_ARGISNULL(3)) {
+ if (!PG_ARGISNULL(3))
+ {
nodatavalueexpr = text_to_cstring(PG_GETARG_TEXT_P(3));
len = strlen("SELECT ") + strlen(nodatavalueexpr);
initndvexpr = (char *)palloc(len + 1);
**/
ret = SPI_execute(newexpr, FALSE, 0);
- if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
+ if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1)
+ {
elog(ERROR, "RASTER_mapAlgebra: Invalid construction for nodata "
"expression. Aborting");
lwfree(expression);
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
+
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
+
rt_context_destroy(ctx);
if (SPI_tuptable)
SPI_freetuptable(tuptable);
/* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_NULL();
}
* right now a raster filled with the nodatavalueexpr
* TODO: Call rt_band_check_isnodata instead?
**/
- if (rt_band_get_isnodata_flag(ctx, band)) {
+ if (rt_band_get_isnodata_flag(ctx, band))
+ {
POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: Band is a nodata band, returning "
"a raster filled with nodata");
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster) PG_RETURN_NULL();
+ if (NULL == pgraster)
+ {
+ rt_raster_destroy(ctx, newrast);
+ rt_raster_destroy(ctx, raster);
+ rt_context_destroy(ctx);
+ elog(ERROR, "RASTER_mapAlgebra: Could not serialize raster. "
+ "Returning NULL");
+ PG_RETURN_NULL();
+ }
SET_VARSIZE(pgraster, pgraster->size);
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
- rt_context_destroy(ctx);
+ rt_raster_destroy(ctx, newrast);
/* Disconnect function from SPI manager */
/* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_POINTER(pgraster);
}
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster)
+ if (NULL == pgraster)
{
/* Free memory allocated out of the current context */
if (expression)
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
PG_RETURN_NULL();
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
- /* Disconnect function from SPI manager */
- /* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ /* Disconnect function from SPI manager */
+ SPI_finish();
PG_RETURN_POINTER(pgraster);
}
* Optimization: If expression resume to a constant (it does not contain
* RAST)
**/
- if (initexpr != NULL && strstr(initexpr, "RAST") == NULL) {
+ if (initexpr != NULL && strstr(initexpr, "RAST") == NULL)
+ {
/* Execute the expresion into newval */
ret = SPI_execute(initexpr, FALSE, 0);
- if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
- elog(ERROR, "RASTER_mapAlgebra: Invalid construction for expression. Aborting");
+ if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1)
+ {
+ elog(ERROR, "RASTER_mapAlgebra: Invalid construction for expression."
+ " Aborting");
/* Free memory allocated out of the current context */
if (expression)
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx,newrast);
rt_context_destroy(ctx);
if (SPI_tuptable)
SPI_freetuptable(tuptable);
/* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_NULL();
}
if (expression == NULL || skipcomputation == 2) {
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster)
+ if (NULL == pgraster)
{
/* Free memory allocated out of the current context */
if (expression)
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
PG_RETURN_NULL();
/* Disconnect function from SPI manager */
/* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_POINTER(pgraster);
}
/* Get the new raster band */
newband = rt_raster_get_band(ctx, newrast, 0);
- if ( ! newband ) {
- elog(WARNING, "RASTER_mapAlgebra: Could not modify band for new raster. "
- "Returning new raster with the original band");
+ if ( ! newband )
+ {
+ elog(NOTICE, "Could not modify band for new raster. Returning new "
+ "raster with the original band");
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
PG_RETURN_NULL();
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
/* Disconnect function from SPI manager */
- /* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_POINTER(pgraster);
}
if (initexpr != NULL) {
newexpr = replace(initexpr, "RAST", strnewval, &count);
- POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: (%dx%d), r = %s, newexpr = %s",
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: (%dx%d), "
+ "r = %s, newexpr = %s",
x, y, strnewval, newexpr);
ret = SPI_execute(newexpr, FALSE, 0);
- if (ret != SPI_OK_SELECT || SPI_tuptable == NULL || SPI_processed != 1) {
- elog(ERROR, "RASTER_mapAlgebra: Invalid construction for expression. Aborting");
+ if (ret != SPI_OK_SELECT || SPI_tuptable == NULL ||
+ SPI_processed != 1)
+ {
+ elog(ERROR, "RASTER_mapAlgebra: Invalid construction"
+ " for expression. Aborting");
/* Free memory allocated out of the current context */
if (expression)
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
if (SPI_tuptable)
SPI_freetuptable(tuptable);
/* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
PG_RETURN_NULL();
}
else
newval = newinitialvalue;
- POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: new value = %f", newval);
+ POSTGIS_RT_DEBUGF(3, "RASTER_mapAlgebra: new value = %f",
+ newval);
}
POSTGIS_RT_DEBUG(3, "RASTER_mapAlgebra: raster modified, serializing it.");
/* Serialize created raster */
pgraster = rt_raster_serialize(ctx, newrast);
- if (!pgraster)
+ if (NULL == pgraster)
{
/* Free memory allocated out of the current context */
if (expression)
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
PG_RETURN_NULL();
if (nodatavalueexpr)
lwfree(nodatavalueexpr);
rt_raster_destroy(ctx, raster);
+ rt_raster_destroy(ctx, newrast);
rt_context_destroy(ctx);
/* Disconnect function from SPI manager */
- /* TODO: make postgres to crash when dealing with BIG rasters */
- //SPI_finish();
+ SPI_finish();
POSTGIS_RT_DEBUG(4, "RASTER_mapAlgebra: returning raster");
+
PG_RETURN_POINTER(pgraster);
}