From: Bborie Park Date: Thu, 14 Jul 2011 14:54:49 +0000 (+0000) Subject: Refactored functions returning sets to use Datums instead of C strings, which were... X-Git-Tag: 2.0.0alpha1~1204 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=65caa54e1fc941ce0a82eff02a427bc2408c742c;p=postgis Refactored functions returning sets to use Datums instead of C strings, which were causing rounding issues particularly for ST_Metadata. This refactoring affected RASTER_metadata, RASTER_bandmetadata, RASTER_summarystats, RASTER_histogram, RASTER_quantile, RASTER_valuecount and RASTER_gdaldrivers. Also refactored the ST_Raster2World* and ST_World2Raster* functions to get the raster's metadata in one call using ST_Metadata rather than individual calls for the georeference components git-svn-id: http://svn.osgeo.org/postgis/trunk@7638 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c index 8ce4a74ef..ddaf0e4d2 100644 --- a/raster/rt_pg/rt_pg.c +++ b/raster/rt_pg/rt_pg.c @@ -3070,11 +3070,10 @@ Datum RASTER_summaryStats(PG_FUNCTION_ARGS) rt_bandstats stats = NULL; TupleDesc tupdesc; - AttInMetadata *attinmeta; - int i = 0; - char **values = NULL; - int values_length = 0; + bool *nulls = NULL; + Datum values[8]; + int values_length = 8; HeapTuple tuple; Datum result; @@ -3156,94 +3155,34 @@ Datum RASTER_summaryStats(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); + BlessTupleDesc(tupdesc); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - if (!cstddev) - values_length = 6; - else - values_length = 8; - values = (char **) palloc(values_length * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[3] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[4] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[5] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - if (cstddev) { - values[6] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[7] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - } + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; - snprintf( - values[0], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - stats->count - ); - snprintf( - values[1], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - stats->sum - ); - snprintf( - values[2], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - stats->mean - ); - snprintf( - values[3], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - stats->stddev - ); - snprintf( - values[4], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - stats->min - ); - snprintf( - values[5], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - stats->max - ); + values[0] = Int64GetDatum(stats->count); + values[1] = Float8GetDatum(stats->sum); + values[2] = Float8GetDatum(stats->mean); + values[3] = Float8GetDatum(stats->stddev); + values[4] = Float8GetDatum(stats->min); + values[5] = Float8GetDatum(stats->max); if (cstddev) { - snprintf( - values[6], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - cM - ); - snprintf( - values[7], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - cQ - ); + values[6] = Float8GetDatum(cM); + values[7] = Float8GetDatum(cQ); + } + else { + nulls[6] = TRUE; + nulls[7] = TRUE; } /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); /* clean up */ - for (i = 0; i < values_length; i++) pfree(values[i]); - pfree(values); + pfree(nulls); pfree(stats); PG_RETURN_DATUM(result); @@ -3269,8 +3208,8 @@ Datum RASTER_histogram(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tupdesc; - AttInMetadata *attinmeta; + int i; int count; rt_histogram hist; rt_histogram hist2; @@ -3297,7 +3236,6 @@ Datum RASTER_histogram(PG_FUNCTION_ARGS) double max = 0; rt_bandstats stats = NULL; - int i; int j; int n; @@ -3474,12 +3412,9 @@ Datum RASTER_histogram(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); - funcctx->attinmeta = attinmeta; + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + MemoryContextSwitchTo(oldcontext); } @@ -3488,66 +3423,35 @@ Datum RASTER_histogram(PG_FUNCTION_ARGS) call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; - attinmeta = funcctx->attinmeta; + tupdesc = funcctx->tuple_desc; hist2 = funcctx->user_fctx; /* do when there is more left to send */ if (call_cntr < max_calls) { - char **values; + int values_length = 4; + Datum values[values_length]; + bool *nulls = NULL; HeapTuple tuple; Datum result; POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(4 * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[2] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[3] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - - snprintf( - values[0], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - hist2[call_cntr].min - ); - snprintf( - values[1], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - hist2[call_cntr].max - ); - snprintf( - values[2], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - hist2[call_cntr].count - ); - snprintf( - values[3], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - hist2[call_cntr].percent - ); + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; + + values[0] = Float8GetDatum(hist2[call_cntr].min); + values[1] = Float8GetDatum(hist2[call_cntr].max); + values[2] = Int64GetDatum(hist2[call_cntr].count); + values[3] = Float8GetDatum(hist2[call_cntr].percent); /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ - pfree(values[3]); - pfree(values[2]); - pfree(values[1]); - pfree(values[0]); - pfree(values); + /* clean up */ + pfree(nulls); SRF_RETURN_NEXT(funcctx, result); } @@ -3572,8 +3476,8 @@ Datum RASTER_quantile(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tupdesc; - AttInMetadata *attinmeta; + int i; int count; rt_quantile quant; rt_quantile quant2; @@ -3596,7 +3500,6 @@ Datum RASTER_quantile(PG_FUNCTION_ARGS) double quantile = 0; rt_bandstats stats = NULL; - int i; int j; int n; @@ -3757,12 +3660,9 @@ Datum RASTER_quantile(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); - funcctx->attinmeta = attinmeta; + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + MemoryContextSwitchTo(oldcontext); } @@ -3771,50 +3671,33 @@ Datum RASTER_quantile(PG_FUNCTION_ARGS) call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; - attinmeta = funcctx->attinmeta; + tupdesc = funcctx->tuple_desc; quant2 = funcctx->user_fctx; /* do when there is more left to send */ if (call_cntr < max_calls) { - char **values; + int values_length = 2; + Datum values[values_length]; + bool *nulls = NULL; HeapTuple tuple; Datum result; POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(2 * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - - snprintf( - values[0], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - quant2[call_cntr].quantile - ); - snprintf( - values[1], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - quant2[call_cntr].value - ); + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; + + values[0] = Float8GetDatum(quant2[call_cntr].quantile); + values[1] = Float8GetDatum(quant2[call_cntr].value); /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ - pfree(values[1]); - pfree(values[0]); - pfree(values); + /* clean up */ + pfree(nulls); SRF_RETURN_NEXT(funcctx, result); } @@ -3836,8 +3719,8 @@ PG_FUNCTION_INFO_V1(RASTER_valueCount); Datum RASTER_valueCount(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tupdesc; - AttInMetadata *attinmeta; + int i; int count; rt_valuecount vcnts; rt_valuecount vcnts2; @@ -3858,7 +3741,6 @@ Datum RASTER_valueCount(PG_FUNCTION_ARGS) { int search_values_count = 0; double roundto = 0; - int i; int j; int n; @@ -3994,12 +3876,9 @@ Datum RASTER_valueCount(PG_FUNCTION_ARGS) { )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); - funcctx->attinmeta = attinmeta; + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; + MemoryContextSwitchTo(oldcontext); } @@ -4008,58 +3887,34 @@ Datum RASTER_valueCount(PG_FUNCTION_ARGS) { call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; - attinmeta = funcctx->attinmeta; + tupdesc = funcctx->tuple_desc; vcnts2 = funcctx->user_fctx; /* do when there is more left to send */ if (call_cntr < max_calls) { - char **values; + int values_length = 3; + Datum values[values_length]; + bool *nulls = NULL; HeapTuple tuple; Datum result; POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(3 * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - - snprintf( - values[0], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - vcnts2[call_cntr].value - ); - snprintf( - values[1], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - vcnts2[call_cntr].count - ); - snprintf( - values[2], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - vcnts2[call_cntr].percent - ); + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; + + values[0] = Float8GetDatum(vcnts2[call_cntr].value); + values[1] = UInt32GetDatum(vcnts2[call_cntr].count); + values[2] = Float8GetDatum(vcnts2[call_cntr].percent); /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ - pfree(values[2]); - pfree(values[1]); - pfree(values[0]); - pfree(values); + /* clean up */ + pfree(nulls); SRF_RETURN_NEXT(funcctx, result); } @@ -4741,8 +4596,8 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; TupleDesc tupdesc; - AttInMetadata *attinmeta; + int i; uint32_t drv_count; rt_gdaldriver drv_set; rt_gdaldriver drv_set2; @@ -4784,12 +4639,8 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); - funcctx->attinmeta = attinmeta; + BlessTupleDesc(tupdesc); + funcctx->tuple_desc = tupdesc; MemoryContextSwitchTo(oldcontext); } @@ -4798,59 +4649,26 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS) call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; - attinmeta = funcctx->attinmeta; + tupdesc = funcctx->tuple_desc; drv_set2 = funcctx->user_fctx; /* do when there is more left to send */ if (call_cntr < max_calls) { - char **values; + int values_length = 4; + Datum values[values_length]; + bool *nulls; HeapTuple tuple; Datum result; POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(4 * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[1] = (char *) palloc( - (strlen(drv_set2[call_cntr].short_name) + 1) * sizeof(char) - ); - values[2] = (char *) palloc( - (strlen(drv_set2[call_cntr].long_name) + 1) * sizeof(char) - ); - values[3] = (char *) palloc( - (strlen(drv_set2[call_cntr].create_options) + 1) * sizeof(char) - ); - - snprintf( - values[0], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - drv_set2[call_cntr].idx - ); - snprintf( - values[1], - (strlen(drv_set2[call_cntr].short_name) + 1) * sizeof(char), - "%s", - drv_set2[call_cntr].short_name - ); - snprintf( - values[2], - (strlen(drv_set2[call_cntr].long_name) + 1) * sizeof(char), - "%s", - drv_set2[call_cntr].long_name - ); - snprintf( - values[3], - (strlen(drv_set2[call_cntr].create_options) + 1) * sizeof(char), - "%s", - drv_set2[call_cntr].create_options - ); + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; + + values[0] = Int32GetDatum(drv_set2[call_cntr].idx); + values[1] = CStringGetTextDatum(drv_set2[call_cntr].short_name); + values[2] = CStringGetTextDatum(drv_set2[call_cntr].long_name); + values[3] = CStringGetTextDatum(drv_set2[call_cntr].create_options); POSTGIS_RT_DEBUGF(4, "Result %d, Index %s", call_cntr, values[0]); POSTGIS_RT_DEBUGF(4, "Result %d, Short Name %s", call_cntr, values[1]); @@ -4858,17 +4676,13 @@ Datum RASTER_getGDALDrivers(PG_FUNCTION_ARGS) POSTGIS_RT_DEBUGF(5, "Result %d, Create Options %s", call_cntr, values[3]); /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); - /* clean up (this is not really necessary) */ - pfree(values[3]); - pfree(values[2]); - pfree(values[1]); - pfree(values[0]); - pfree(values); + /* clean up */ + pfree(nulls); SRF_RETURN_NEXT(funcctx, result); } @@ -5090,7 +4904,7 @@ Datum RASTER_metadata(PG_FUNCTION_ARGS) rt_pgraster *pgraster = NULL; rt_raster raster = NULL; - uint16_t numBands; + uint32_t numBands; double scaleX; double scaleY; double ipX; @@ -5098,15 +4912,14 @@ Datum RASTER_metadata(PG_FUNCTION_ARGS) double skewX; double skewY; int32_t srid; - uint16_t width; - uint16_t height; - - TupleDesc tupdesc; - AttInMetadata *attinmeta; + uint32_t width; + uint32_t height; int i = 0; - char **values = NULL; + TupleDesc tupdesc; + bool *nulls = NULL; int values_length = 10; + Datum values[values_length]; HeapTuple tuple; Datum result; @@ -5159,100 +4972,30 @@ Datum RASTER_metadata(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); + BlessTupleDesc(tupdesc); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(values_length * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[2] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[3] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[4] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[5] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[6] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[7] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[8] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[9] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - - snprintf( - values[0], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - ipX - ); - snprintf( - values[1], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - ipY - ); - snprintf( - values[2], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - width - ); - snprintf( - values[3], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - height - ); - snprintf( - values[4], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - scaleX - ); - snprintf( - values[5], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - scaleY - ); - snprintf( - values[6], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - skewX - ); - snprintf( - values[7], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - skewY - ); - snprintf( - values[8], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - srid - ); - snprintf( - values[9], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - numBands - ); + values[0] = Float8GetDatum(ipX); + values[1] = Float8GetDatum(ipY); + values[2] = UInt32GetDatum(width); + values[3] = UInt32GetDatum(height); + values[4] = Float8GetDatum(scaleX); + values[5] = Float8GetDatum(scaleY); + values[6] = Float8GetDatum(skewX); + values[7] = Float8GetDatum(skewY); + values[8] = Int32GetDatum(srid); + values[9] = UInt32GetDatum(numBands); + + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); /* clean up */ - for (i = 0; i < values_length; i++) pfree(values[i]); - pfree(values); + pfree(nulls); PG_RETURN_DATUM(result); } @@ -5267,20 +5010,20 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS) rt_raster raster = NULL; rt_band band = NULL; - TupleDesc tupdesc; - AttInMetadata *attinmeta; - uint32_t numBands; uint32_t bandindex = 1; - const char *pixtypename = NULL; + const char *tmp = NULL; + char *pixtypename = NULL; bool hasnodatavalue = FALSE; double nodatavalue; - const char *bandpath = NULL; + char *bandpath = NULL; bool isoutdb = FALSE; int i = 0; - char **values = NULL; + TupleDesc tupdesc; + bool *nulls = NULL; int values_length = 5; + Datum values[values_length]; HeapTuple tuple; Datum result; @@ -5323,7 +5066,9 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS) } /* pixeltype */ - pixtypename = rt_pixtype_name(rt_band_get_pixtype(band)); + tmp = rt_pixtype_name(rt_band_get_pixtype(band)); + pixtypename = palloc(sizeof(char) * (strlen(tmp) + 1)); + strncpy(pixtypename, tmp, strlen(tmp) + 1); /* hasnodatavalue */ if (rt_band_get_hasnodata_flag(band)) hasnodatavalue = TRUE; @@ -5332,7 +5077,11 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS) nodatavalue = rt_band_get_nodata(band); /* path */ - bandpath = rt_band_get_ext_path(band); + tmp = rt_band_get_ext_path(band); + if (tmp) { + bandpath = palloc(sizeof(char) * (strlen(tmp) + 1)); + strncpy(bandpath, tmp, strlen(tmp) + 1); + } /* isoutdb */ isoutdb = bandpath ? TRUE : FALSE; @@ -5352,72 +5101,30 @@ Datum RASTER_bandmetadata(PG_FUNCTION_ARGS) )); } - /* - * generate attribute metadata needed later to produce tuples from raw - * C strings - */ - attinmeta = TupleDescGetAttInMetadata(tupdesc); + BlessTupleDesc(tupdesc); - /* - * Prepare a values array for building the returned tuple. - * This should be an array of C strings which will - * be processed later by the type input functions. - */ - values = (char **) palloc(values_length * sizeof(char *)); - - values[0] = (char *) palloc(sizeof(char) * (strlen(pixtypename) + 1)); - values[1] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1)); - values[3] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1)); - if (bandpath) - values[4] = (char *) palloc(sizeof(char) * (strlen(bandpath) + 1)); + nulls = palloc(sizeof(bool) * values_length); + for (i = 0; i < values_length; i++) nulls[i] = FALSE; + + values[0] = CStringGetTextDatum(pixtypename); + values[1] = BoolGetDatum(hasnodatavalue); + values[2] = Float8GetDatum(nodatavalue); + values[3] = BoolGetDatum(isoutdb); + if (bandpath && strlen(bandpath)) + values[4] = CStringGetTextDatum(bandpath); else - values[4] = NULL; - - snprintf( - values[0], - sizeof(char) * (strlen(pixtypename) + 1), - "%s", - pixtypename - ); - snprintf( - values[1], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - hasnodatavalue - ); - snprintf( - values[2], - sizeof(char) * (MAX_DBL_CHARLEN + 1), - "%f", - nodatavalue - ); - snprintf( - values[3], - sizeof(char) * (MAX_INT_CHARLEN + 1), - "%d", - isoutdb - ); - if (bandpath) { - snprintf( - values[4], - sizeof(char) * (strlen(bandpath) + 1), - "%s", - bandpath - ); - } + nulls[4] = TRUE; /* build a tuple */ - tuple = BuildTupleFromCStrings(attinmeta, values); + tuple = heap_form_tuple(tupdesc, values, nulls); /* make the tuple into a datum */ result = HeapTupleGetDatum(tuple); /* clean up */ - for (i = 0; i < values_length; i++) { - if (NULL != values[i]) pfree(values[i]); - } - pfree(values); + pfree(nulls); + pfree(pixtypename); + if (bandpath) pfree(bandpath); PG_RETURN_DATUM(result); } diff --git a/raster/rt_pg/rtpostgis.sql.in.c b/raster/rt_pg/rtpostgis.sql.in.c index e01a4d1b1..f43a30c5b 100644 --- a/raster/rt_pg/rtpostgis.sql.in.c +++ b/raster/rt_pg/rtpostgis.sql.in.c @@ -2051,12 +2051,7 @@ CREATE OR REPLACE FUNCTION st_world2rastercoordx(rast raster, xw float8, yw floa f float8 := 0.0; xr numeric := 0.0; BEGIN - a := st_scalex(rast); - d := st_skewy(rast); - b := st_skewx(rast); - e := st_scaley(rast); - c := st_upperleftx(rast); - f := st_upperlefty(rast); + SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast); IF ( b * d - a * e = 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0'; END IF; @@ -2086,12 +2081,7 @@ CREATE OR REPLACE FUNCTION st_world2rastercoordx(rast raster, xw float8) f float8 := 0.0; xr numeric := 0.0; BEGIN - a := st_scalex(rast); - d := st_skewy(rast); - b := st_skewx(rast); - e := st_scaley(rast); - c := st_upperleftx(rast); - f := st_upperlefty(rast); + SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast); IF ( b * d - a * e = 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0'; END IF; @@ -2140,12 +2130,7 @@ CREATE OR REPLACE FUNCTION st_world2rastercoordy(rast raster, xw float8, yw floa f float8 := 0.0; yr numeric := 0.0; BEGIN - a := st_scalex(rast); - d := st_skewy(rast); - b := st_skewx(rast); - e := st_scaley(rast); - c := st_upperleftx(rast); - f := st_upperlefty(rast); + SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast); IF ( b * d - a * e = 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0'; END IF; @@ -2175,12 +2160,7 @@ CREATE OR REPLACE FUNCTION st_world2rastercoordy(rast raster, yw float8) f float8 := 0.0; yr numeric := 0.0; BEGIN - a := st_scalex(rast); - d := st_skewy(rast); - b := st_skewx(rast); - e := st_scaley(rast); - c := st_upperleftx(rast); - f := st_upperlefty(rast); + SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast); IF ( b * d - a * e = 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0'; END IF; @@ -2227,9 +2207,7 @@ CREATE OR REPLACE FUNCTION st_raster2worldcoordx(rast raster, xr int, yr int) c float8 := 0.0; xw numeric := 0.0; BEGIN - a := st_scalex(rast); - b := st_skewx(rast); - c := st_upperleftx(rast); + SELECT scalex, skewx, upperleftx INTO a, b, c FROM ST_Metadata(rast); xw := (a::numeric * (xr::numeric - 1.0) + b::numeric * (yr::numeric - 1.0) + c::numeric)::numeric; RETURN xw; END; @@ -2254,9 +2232,7 @@ CREATE OR REPLACE FUNCTION st_raster2worldcoordx(rast raster, xr int) c float8 := 0.0; xw numeric := 0.0; BEGIN - a := st_scalex(rast); - b := st_skewx(rast); - c := st_upperleftx(rast); + SELECT scalex, skewx, upperleftx INTO a, b, c FROM ST_Metadata(rast); IF ( b != 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinates on a raster with rotation providing X only. A Y coordinate must also be provided'; END IF; @@ -2282,9 +2258,7 @@ CREATE OR REPLACE FUNCTION st_raster2worldcoordy(rast raster, xr int, yr int) f float8 := 0.0; yw numeric := 0.0; BEGIN - d := st_skewy(rast); - e := st_scaley(rast); - f := st_upperlefty(rast); + SELECT skewy, scaley, upperlefty INTO d, e, f FROM ST_Metadata(rast); yw := (d::numeric * (xr::numeric - 1.0) + e::numeric * (yr::numeric - 1.0) + f::numeric)::numeric; RETURN yw; END; @@ -2309,9 +2283,7 @@ CREATE OR REPLACE FUNCTION st_raster2worldcoordy(rast raster, yr int) f float8 := 0.0; yw numeric := 0.0; BEGIN - d := st_skewy(rast); - e := st_scaley(rast); - f := st_upperlefty(rast); + SELECT skewy, scaley, upperlefty INTO d, e, f FROM ST_Metadata(rast); IF ( d != 0 ) THEN RAISE EXCEPTION 'Attempting to compute raster coordinates on a raster with rotation providing Y only. An X coordinate must also be provided'; END IF; diff --git a/raster/test/regress/rt_bandmetadata.sql b/raster/test/regress/rt_bandmetadata.sql index 222de30cb..3b276d40c 100644 --- a/raster/test/regress/rt_bandmetadata.sql +++ b/raster/test/regress/rt_bandmetadata.sql @@ -1,4 +1,10 @@ -SELECT * FROM ST_BandMetaData( +SELECT + pixeltype, + hasnodatavalue, + round(nodatavalue::numeric, 3), + isoutdb, + path +FROM ST_BandMetaData( ST_SetValue( ST_SetValue( ST_SetValue( @@ -13,7 +19,13 @@ SELECT * FROM ST_BandMetaData( , 1, 5, 5, 3.14159 ) ); -SELECT * FROM ST_BandMetaData( +SELECT + pixeltype, + hasnodatavalue, + round(nodatavalue::numeric, 3), + isoutdb, + path +FROM ST_BandMetaData( ST_SetValue( ST_SetValue( ST_SetValue( @@ -29,7 +41,13 @@ SELECT * FROM ST_BandMetaData( ), 1 ); -SELECT * FROM ST_BandMetaData( +SELECT + pixeltype, + hasnodatavalue, + round(nodatavalue::numeric, 3), + isoutdb, + path +FROM ST_BandMetaData( ST_SetValue( ST_SetValue( ST_SetValue( diff --git a/raster/test/regress/rt_bandmetadata_expected b/raster/test/regress/rt_bandmetadata_expected index 0aa43866d..4824dbc28 100644 --- a/raster/test/regress/rt_bandmetadata_expected +++ b/raster/test/regress/rt_bandmetadata_expected @@ -1,4 +1,4 @@ -64BF|t|0|f| -64BF|t|0|f| +64BF|t|0.000|f| +64BF|t|0.000|f| NOTICE: Invalid band index (must use 1-based). Returning NULL |||| diff --git a/raster/test/regress/rt_count.sql b/raster/test/regress/rt_count.sql index ef5779c7b..75a4396da 100644 --- a/raster/test/regress/rt_count.sql +++ b/raster/test/regress/rt_count.sql @@ -91,4 +91,3 @@ SELECT ST_Count('test', 'rast', 1); SELECT ST_Count('test', 'rast', FALSE); SELECT ST_Count('test', 'rast'); ROLLBACK; -