]> granicus.if.org Git - postgis/commitdiff
Refactored functions returning sets to use Datums instead of C strings, which were...
authorBborie Park <bkpark at ucdavis.edu>
Thu, 14 Jul 2011 14:54:49 +0000 (14:54 +0000)
committerBborie Park <bkpark at ucdavis.edu>
Thu, 14 Jul 2011 14:54:49 +0000 (14:54 +0000)
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

raster/rt_pg/rt_pg.c
raster/rt_pg/rtpostgis.sql.in.c
raster/test/regress/rt_bandmetadata.sql
raster/test/regress/rt_bandmetadata_expected
raster/test/regress/rt_count.sql

index 8ce4a74efd9ec84d40a06f5e6425732a193ac1db..ddaf0e4d267a837608bd554b5a8a8f4afa40e2cf 100644 (file)
@@ -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);
 }
index e01a4d1b193c6ff3aa6a196b60c5e8ba3f528a48..f43a30c5b3d763d1089959ad49c653d7efa10539 100644 (file)
@@ -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;
index 222de30cbc32124510ef94ac6851265cdf2c4ded..3b276d40cac75523e90f091e777ae5899a7f7448 100644 (file)
@@ -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(
index 0aa43866dc0cd4c0b47ed89b724b162b189fcae2..4824dbc28b9fe61bd304b7e7b3531f53ff5985db 100644 (file)
@@ -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
 ||||
index ef5779c7bc557e12ed6f192b6d8cedc2545cad96..75a4396da17dbdd8aabba4d4c56f35c938885b7b 100644 (file)
@@ -91,4 +91,3 @@ SELECT ST_Count('test', 'rast', 1);
 SELECT ST_Count('test', 'rast', FALSE);
 SELECT ST_Count('test', 'rast');
 ROLLBACK;
-