Changeset 7638


Ignore:
Timestamp:
Jul 14, 2011 7:54:49 AM (5 years ago)
Author:
dustymugs
Message:

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

Location:
trunk/raster
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/raster/rt_pg/rt_pg.c

    r7633 r7638  
    30713071
    30723072        TupleDesc tupdesc;
    3073         AttInMetadata *attinmeta;
    3074 
    30753073        int i = 0;
    3076         char **values = NULL;
    3077         int values_length = 0;
     3074        bool *nulls = NULL;
     3075        Datum values[8];
     3076        int values_length = 8;
    30783077        HeapTuple tuple;
    30793078        Datum result;
     
    31573156        }
    31583157
    3159         /*
    3160          * generate attribute metadata needed later to produce tuples from raw
    3161          * C strings
    3162          */
    3163         attinmeta = TupleDescGetAttInMetadata(tupdesc);
    3164 
    3165         /*
    3166          * Prepare a values array for building the returned tuple.
    3167          * This should be an array of C strings which will
    3168          * be processed later by the type input functions.
    3169          */
    3170         if (!cstddev)
    3171                 values_length = 6;
    3172         else
    3173                 values_length = 8;
    3174         values = (char **) palloc(values_length * sizeof(char *));
    3175 
    3176         values[0] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    3177         values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3178         values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3179         values[3] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3180         values[4] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3181         values[5] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
     3158        BlessTupleDesc(tupdesc);
     3159
     3160        nulls = palloc(sizeof(bool) * values_length);
     3161        for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     3162
     3163        values[0] = Int64GetDatum(stats->count);
     3164        values[1] = Float8GetDatum(stats->sum);
     3165        values[2] = Float8GetDatum(stats->mean);
     3166        values[3] = Float8GetDatum(stats->stddev);
     3167        values[4] = Float8GetDatum(stats->min);
     3168        values[5] = Float8GetDatum(stats->max);
    31823169        if (cstddev) {
    3183                 values[6] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3184                 values[7] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3185         }
    3186 
    3187         snprintf(
    3188                 values[0],
    3189                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    3190                 "%d",
    3191                 stats->count
    3192         );
    3193         snprintf(
    3194                 values[1],
    3195                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3196                 "%f",
    3197                 stats->sum
    3198         );
    3199         snprintf(
    3200                 values[2],
    3201                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3202                 "%f",
    3203                 stats->mean
    3204         );
    3205         snprintf(
    3206                 values[3],
    3207                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3208                 "%f",
    3209                 stats->stddev
    3210         );
    3211         snprintf(
    3212                 values[4],
    3213                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3214                 "%f",
    3215                 stats->min
    3216         );
    3217         snprintf(
    3218                 values[5],
    3219                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3220                 "%f",
    3221                 stats->max
    3222         );
    3223         if (cstddev) {
    3224                 snprintf(
    3225                         values[6],
    3226                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3227                         "%f",
    3228                         cM
    3229                 );
    3230                 snprintf(
    3231                         values[7],
    3232                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3233                         "%f",
    3234                         cQ
    3235                 );
     3170                values[6] = Float8GetDatum(cM);
     3171                values[7] = Float8GetDatum(cQ);
     3172        }
     3173        else {
     3174                nulls[6] = TRUE;
     3175                nulls[7] = TRUE;
    32363176        }
    32373177
    32383178        /* build a tuple */
    3239         tuple = BuildTupleFromCStrings(attinmeta, values);
     3179        tuple = heap_form_tuple(tupdesc, values, nulls);
    32403180
    32413181        /* make the tuple into a datum */
     
    32433183
    32443184        /* clean up */
    3245         for (i = 0; i < values_length; i++) pfree(values[i]);
    3246         pfree(values);
     3185        pfree(nulls);
    32473186        pfree(stats);
    32483187
     
    32703209        FuncCallContext *funcctx;
    32713210        TupleDesc tupdesc;
    3272         AttInMetadata *attinmeta;
    3273 
     3211
     3212        int i;
    32743213        int count;
    32753214        rt_histogram hist;
     
    32983237                rt_bandstats stats = NULL;
    32993238
    3300                 int i;
    33013239                int j;
    33023240                int n;
     
    34753413                }
    34763414
    3477                 /*
    3478                  * generate attribute metadata needed later to produce tuples from raw
    3479                  * C strings
    3480                  */
    3481                 attinmeta = TupleDescGetAttInMetadata(tupdesc);
    3482                 funcctx->attinmeta = attinmeta;
     3415                BlessTupleDesc(tupdesc);
     3416                funcctx->tuple_desc = tupdesc;
     3417
    34833418                MemoryContextSwitchTo(oldcontext);
    34843419        }
     
    34893424        call_cntr = funcctx->call_cntr;
    34903425        max_calls = funcctx->max_calls;
    3491         attinmeta = funcctx->attinmeta;
     3426        tupdesc = funcctx->tuple_desc;
    34923427        hist2 = funcctx->user_fctx;
    34933428
    34943429        /* do when there is more left to send */
    34953430        if (call_cntr < max_calls) {
    3496                 char **values;
     3431                int values_length = 4;
     3432                Datum values[values_length];
     3433                bool *nulls = NULL;
    34973434                HeapTuple tuple;
    34983435                Datum result;
     
    35003437                POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr);
    35013438
    3502                 /*
    3503                  * Prepare a values array for building the returned tuple.
    3504                  * This should be an array of C strings which will
    3505                  * be processed later by the type input functions.
    3506                  */
    3507                 values = (char **) palloc(4 * sizeof(char *));
    3508 
    3509                 values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3510                 values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3511                 values[2] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    3512                 values[3] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3513 
    3514                 snprintf(
    3515                         values[0],
    3516                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3517                         "%f",
    3518                         hist2[call_cntr].min
    3519                 );
    3520                 snprintf(
    3521                         values[1],
    3522                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3523                         "%f",
    3524                         hist2[call_cntr].max
    3525                 );
    3526                 snprintf(
    3527                         values[2],
    3528                         sizeof(char) * (MAX_INT_CHARLEN + 1),
    3529                         "%d",
    3530                         hist2[call_cntr].count
    3531                 );
    3532                 snprintf(
    3533                         values[3],
    3534                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3535                         "%f",
    3536                         hist2[call_cntr].percent
    3537                 );
     3439                nulls = palloc(sizeof(bool) * values_length);
     3440                for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     3441
     3442                values[0] = Float8GetDatum(hist2[call_cntr].min);
     3443                values[1] = Float8GetDatum(hist2[call_cntr].max);
     3444                values[2] = Int64GetDatum(hist2[call_cntr].count);
     3445                values[3] = Float8GetDatum(hist2[call_cntr].percent);
    35383446
    35393447                /* build a tuple */
    3540                 tuple = BuildTupleFromCStrings(attinmeta, values);
     3448                tuple = heap_form_tuple(tupdesc, values, nulls);
    35413449
    35423450                /* make the tuple into a datum */
    35433451                result = HeapTupleGetDatum(tuple);
    35443452
    3545                 /* clean up (this is not really necessary) */
    3546                 pfree(values[3]);
    3547                 pfree(values[2]);
    3548                 pfree(values[1]);
    3549                 pfree(values[0]);
    3550                 pfree(values);
     3453                /* clean up */
     3454                pfree(nulls);
    35513455
    35523456                SRF_RETURN_NEXT(funcctx, result);
     
    35733477        FuncCallContext *funcctx;
    35743478        TupleDesc tupdesc;
    3575         AttInMetadata *attinmeta;
    3576 
     3479
     3480        int i;
    35773481        int count;
    35783482        rt_quantile quant;
     
    35973501                rt_bandstats stats = NULL;
    35983502
    3599                 int i;
    36003503                int j;
    36013504                int n;
     
    37583661                }
    37593662
    3760                 /*
    3761                  * generate attribute metadata needed later to produce tuples from raw
    3762                  * C strings
    3763                  */
    3764                 attinmeta = TupleDescGetAttInMetadata(tupdesc);
    3765                 funcctx->attinmeta = attinmeta;
     3663                BlessTupleDesc(tupdesc);
     3664                funcctx->tuple_desc = tupdesc;
     3665
    37663666                MemoryContextSwitchTo(oldcontext);
    37673667        }
     
    37723672        call_cntr = funcctx->call_cntr;
    37733673        max_calls = funcctx->max_calls;
    3774         attinmeta = funcctx->attinmeta;
     3674        tupdesc = funcctx->tuple_desc;
    37753675        quant2 = funcctx->user_fctx;
    37763676
    37773677        /* do when there is more left to send */
    37783678        if (call_cntr < max_calls) {
    3779                 char **values;
     3679                int values_length = 2;
     3680                Datum values[values_length];
     3681                bool *nulls = NULL;
    37803682                HeapTuple tuple;
    37813683                Datum result;
     
    37833685                POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr);
    37843686
    3785                 /*
    3786                  * Prepare a values array for building the returned tuple.
    3787                  * This should be an array of C strings which will
    3788                  * be processed later by the type input functions.
    3789                  */
    3790                 values = (char **) palloc(2 * sizeof(char *));
    3791 
    3792                 values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3793                 values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    3794 
    3795                 snprintf(
    3796                         values[0],
    3797                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3798                         "%f",
    3799                         quant2[call_cntr].quantile
    3800                 );
    3801                 snprintf(
    3802                         values[1],
    3803                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    3804                         "%f",
    3805                         quant2[call_cntr].value
    3806                 );
     3687                nulls = palloc(sizeof(bool) * values_length);
     3688                for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     3689
     3690                values[0] = Float8GetDatum(quant2[call_cntr].quantile);
     3691                values[1] = Float8GetDatum(quant2[call_cntr].value);
    38073692
    38083693                /* build a tuple */
    3809                 tuple = BuildTupleFromCStrings(attinmeta, values);
     3694                tuple = heap_form_tuple(tupdesc, values, nulls);
    38103695
    38113696                /* make the tuple into a datum */
    38123697                result = HeapTupleGetDatum(tuple);
    38133698
    3814                 /* clean up (this is not really necessary) */
    3815                 pfree(values[1]);
    3816                 pfree(values[0]);
    3817                 pfree(values);
     3699                /* clean up */
     3700                pfree(nulls);
    38183701
    38193702                SRF_RETURN_NEXT(funcctx, result);
     
    38373720        FuncCallContext *funcctx;
    38383721        TupleDesc tupdesc;
    3839         AttInMetadata *attinmeta;
    3840 
     3722
     3723        int i;
    38413724        int count;
    38423725        rt_valuecount vcnts;
     
    38593742                double roundto = 0;
    38603743
    3861                 int i;
    38623744                int j;
    38633745                int n;
     
    39953877                }
    39963878
    3997                 /*
    3998                  * generate attribute metadata needed later to produce tuples from raw
    3999                  * C strings
    4000                  */
    4001                 attinmeta = TupleDescGetAttInMetadata(tupdesc);
    4002                 funcctx->attinmeta = attinmeta;
     3879                BlessTupleDesc(tupdesc);
     3880                funcctx->tuple_desc = tupdesc;
     3881
    40033882                MemoryContextSwitchTo(oldcontext);
    40043883        }
     
    40093888        call_cntr = funcctx->call_cntr;
    40103889        max_calls = funcctx->max_calls;
    4011         attinmeta = funcctx->attinmeta;
     3890        tupdesc = funcctx->tuple_desc;
    40123891        vcnts2 = funcctx->user_fctx;
    40133892
    40143893        /* do when there is more left to send */
    40153894        if (call_cntr < max_calls) {
    4016                 char **values;
     3895                int values_length = 3;
     3896                Datum values[values_length];
     3897                bool *nulls = NULL;
    40173898                HeapTuple tuple;
    40183899                Datum result;
     
    40203901                POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr);
    40213902
    4022                 /*
    4023                  * Prepare a values array for building the returned tuple.
    4024                  * This should be an array of C strings which will
    4025                  * be processed later by the type input functions.
    4026                  */
    4027                 values = (char **) palloc(3 * sizeof(char *));
    4028 
    4029                 values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    4030                 values[1] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    4031                 values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    4032 
    4033                 snprintf(
    4034                         values[0],
    4035                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    4036                         "%f",
    4037                         vcnts2[call_cntr].value
    4038                 );
    4039                 snprintf(
    4040                         values[1],
    4041                         sizeof(char) * (MAX_INT_CHARLEN + 1),
    4042                         "%d",
    4043                         vcnts2[call_cntr].count
    4044                 );
    4045                 snprintf(
    4046                         values[2],
    4047                         sizeof(char) * (MAX_DBL_CHARLEN + 1),
    4048                         "%f",
    4049                         vcnts2[call_cntr].percent
    4050                 );
     3903                nulls = palloc(sizeof(bool) * values_length);
     3904                for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     3905
     3906                values[0] = Float8GetDatum(vcnts2[call_cntr].value);
     3907                values[1] = UInt32GetDatum(vcnts2[call_cntr].count);
     3908                values[2] = Float8GetDatum(vcnts2[call_cntr].percent);
    40513909
    40523910                /* build a tuple */
    4053                 tuple = BuildTupleFromCStrings(attinmeta, values);
     3911                tuple = heap_form_tuple(tupdesc, values, nulls);
    40543912
    40553913                /* make the tuple into a datum */
    40563914                result = HeapTupleGetDatum(tuple);
    40573915
    4058                 /* clean up (this is not really necessary) */
    4059                 pfree(values[2]);
    4060                 pfree(values[1]);
    4061                 pfree(values[0]);
    4062                 pfree(values);
     3916                /* clean up */
     3917                pfree(nulls);
    40633918
    40643919                SRF_RETURN_NEXT(funcctx, result);
     
    47424597        FuncCallContext *funcctx;
    47434598        TupleDesc tupdesc;
    4744         AttInMetadata *attinmeta;
    4745 
     4599
     4600        int i;
    47464601        uint32_t drv_count;
    47474602        rt_gdaldriver drv_set;
     
    47854640                }
    47864641
    4787                 /*
    4788                  * generate attribute metadata needed later to produce tuples from raw
    4789                  * C strings
    4790                  */
    4791                 attinmeta = TupleDescGetAttInMetadata(tupdesc);
    4792                 funcctx->attinmeta = attinmeta;
     4642                BlessTupleDesc(tupdesc);
     4643                funcctx->tuple_desc = tupdesc;
    47934644                MemoryContextSwitchTo(oldcontext);
    47944645        }
     
    47994650        call_cntr = funcctx->call_cntr;
    48004651        max_calls = funcctx->max_calls;
    4801         attinmeta = funcctx->attinmeta;
     4652        tupdesc = funcctx->tuple_desc;
    48024653        drv_set2 = funcctx->user_fctx;
    48034654
    48044655        /* do when there is more left to send */
    48054656        if (call_cntr < max_calls) {
    4806                 char **values;
     4657                int values_length = 4;
     4658                Datum values[values_length];
     4659                bool *nulls;
    48074660                HeapTuple tuple;
    48084661                Datum result;
     
    48104663                POSTGIS_RT_DEBUGF(3, "Result %d", call_cntr);
    48114664
    4812                 /*
    4813                  * Prepare a values array for building the returned tuple.
    4814                  * This should be an array of C strings which will
    4815                  * be processed later by the type input functions.
    4816                  */
    4817                 values = (char **) palloc(4 * sizeof(char *));
    4818 
    4819                 values[0] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    4820                 values[1] = (char *) palloc(
    4821                         (strlen(drv_set2[call_cntr].short_name) + 1) * sizeof(char)
    4822                 );
    4823                 values[2] = (char *) palloc(
    4824                         (strlen(drv_set2[call_cntr].long_name) + 1) * sizeof(char)
    4825                 );
    4826                 values[3] = (char *) palloc(
    4827                         (strlen(drv_set2[call_cntr].create_options) + 1) * sizeof(char)
    4828                 );
    4829 
    4830                 snprintf(
    4831                         values[0],
    4832                         sizeof(char) * (MAX_INT_CHARLEN + 1),
    4833                         "%d",
    4834                         drv_set2[call_cntr].idx
    4835                 );
    4836                 snprintf(
    4837                         values[1],
    4838                         (strlen(drv_set2[call_cntr].short_name) + 1) * sizeof(char),
    4839                         "%s",
    4840                         drv_set2[call_cntr].short_name
    4841                 );
    4842                 snprintf(
    4843                         values[2],
    4844                         (strlen(drv_set2[call_cntr].long_name) + 1) * sizeof(char),
    4845                         "%s",
    4846                         drv_set2[call_cntr].long_name
    4847                 );
    4848                 snprintf(
    4849                         values[3],
    4850                         (strlen(drv_set2[call_cntr].create_options) + 1) * sizeof(char),
    4851                         "%s",
    4852                         drv_set2[call_cntr].create_options
    4853                 );
     4665                nulls = palloc(sizeof(bool) * values_length);
     4666                for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     4667
     4668                values[0] = Int32GetDatum(drv_set2[call_cntr].idx);
     4669                values[1] = CStringGetTextDatum(drv_set2[call_cntr].short_name);
     4670                values[2] = CStringGetTextDatum(drv_set2[call_cntr].long_name);
     4671                values[3] = CStringGetTextDatum(drv_set2[call_cntr].create_options);
    48544672
    48554673                POSTGIS_RT_DEBUGF(4, "Result %d, Index %s", call_cntr, values[0]);
     
    48594677
    48604678                /* build a tuple */
    4861                 tuple = BuildTupleFromCStrings(attinmeta, values);
     4679                tuple = heap_form_tuple(tupdesc, values, nulls);
    48624680
    48634681                /* make the tuple into a datum */
    48644682                result = HeapTupleGetDatum(tuple);
    48654683
    4866                 /* clean up (this is not really necessary) */
    4867                 pfree(values[3]);
    4868                 pfree(values[2]);
    4869                 pfree(values[1]);
    4870                 pfree(values[0]);
    4871                 pfree(values);
     4684                /* clean up */
     4685                pfree(nulls);
    48724686
    48734687                SRF_RETURN_NEXT(funcctx, result);
     
    50914905        rt_raster raster = NULL;
    50924906
    5093         uint16_t numBands;
     4907        uint32_t numBands;
    50944908        double scaleX;
    50954909        double scaleY;
     
    50994913        double skewY;
    51004914        int32_t srid;
    5101         uint16_t width;
    5102         uint16_t height;
    5103 
     4915        uint32_t width;
     4916        uint32_t height;
     4917
     4918        int i = 0;
    51044919        TupleDesc tupdesc;
    5105         AttInMetadata *attinmeta;
    5106 
    5107         int i = 0;
    5108         char **values = NULL;
     4920        bool *nulls = NULL;
    51094921        int values_length = 10;
     4922        Datum values[values_length];
    51104923        HeapTuple tuple;
    51114924        Datum result;
     
    51604973        }
    51614974
    5162         /*
    5163          * generate attribute metadata needed later to produce tuples from raw
    5164          * C strings
    5165          */
    5166         attinmeta = TupleDescGetAttInMetadata(tupdesc);
    5167 
    5168         /*
    5169          * Prepare a values array for building the returned tuple.
    5170          * This should be an array of C strings which will
    5171          * be processed later by the type input functions.
    5172          */
    5173         values = (char **) palloc(values_length * sizeof(char *));
    5174 
    5175         values[0] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5176         values[1] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5177         values[2] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5178         values[3] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5179         values[4] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5180         values[5] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5181         values[6] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5182         values[7] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5183         values[8] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5184         values[9] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5185 
    5186         snprintf(
    5187                 values[0],
    5188                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5189                 "%f",
    5190                 ipX
    5191         );
    5192         snprintf(
    5193                 values[1],
    5194                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5195                 "%f",
    5196                 ipY
    5197         );
    5198         snprintf(
    5199                 values[2],
    5200                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5201                 "%d",
    5202                 width
    5203         );
    5204         snprintf(
    5205                 values[3],
    5206                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5207                 "%d",
    5208                 height
    5209         );
    5210         snprintf(
    5211                 values[4],
    5212                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5213                 "%f",
    5214                 scaleX
    5215         );
    5216         snprintf(
    5217                 values[5],
    5218                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5219                 "%f",
    5220                 scaleY
    5221         );
    5222         snprintf(
    5223                 values[6],
    5224                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5225                 "%f",
    5226                 skewX
    5227         );
    5228         snprintf(
    5229                 values[7],
    5230                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5231                 "%f",
    5232                 skewY
    5233         );
    5234         snprintf(
    5235                 values[8],
    5236                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5237                 "%d",
    5238                 srid
    5239         );
    5240         snprintf(
    5241                 values[9],
    5242                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5243                 "%d",
    5244                 numBands
    5245         );
     4975        BlessTupleDesc(tupdesc);
     4976
     4977        values[0] = Float8GetDatum(ipX);
     4978        values[1] = Float8GetDatum(ipY);
     4979        values[2] = UInt32GetDatum(width);
     4980        values[3] = UInt32GetDatum(height);
     4981        values[4] = Float8GetDatum(scaleX);
     4982        values[5] = Float8GetDatum(scaleY);
     4983        values[6] = Float8GetDatum(skewX);
     4984        values[7] = Float8GetDatum(skewY);
     4985        values[8] = Int32GetDatum(srid);
     4986        values[9] = UInt32GetDatum(numBands);
     4987
     4988        nulls = palloc(sizeof(bool) * values_length);
     4989        for (i = 0; i < values_length; i++) nulls[i] = FALSE;
    52464990
    52474991        /* build a tuple */
    5248         tuple = BuildTupleFromCStrings(attinmeta, values);
     4992        tuple = heap_form_tuple(tupdesc, values, nulls);
    52494993
    52504994        /* make the tuple into a datum */
     
    52524996
    52534997        /* clean up */
    5254         for (i = 0; i < values_length; i++) pfree(values[i]);
    5255         pfree(values);
     4998        pfree(nulls);
    52564999
    52575000        PG_RETURN_DATUM(result);
     
    52685011        rt_band band = NULL;
    52695012
    5270         TupleDesc tupdesc;
    5271         AttInMetadata *attinmeta;
    5272 
    52735013        uint32_t numBands;
    52745014        uint32_t bandindex = 1;
    5275         const char *pixtypename = NULL;
     5015        const char *tmp = NULL;
     5016        char *pixtypename = NULL;
    52765017        bool hasnodatavalue = FALSE;
    52775018        double nodatavalue;
    5278         const char *bandpath = NULL;
     5019        char *bandpath = NULL;
    52795020        bool isoutdb = FALSE;
    52805021
    52815022        int i = 0;
    5282         char **values = NULL;
     5023        TupleDesc tupdesc;
     5024        bool *nulls = NULL;
    52835025        int values_length = 5;
     5026        Datum values[values_length];
    52845027        HeapTuple tuple;
    52855028        Datum result;
     
    53245067
    53255068        /* pixeltype */
    5326         pixtypename = rt_pixtype_name(rt_band_get_pixtype(band));
     5069        tmp = rt_pixtype_name(rt_band_get_pixtype(band));
     5070        pixtypename = palloc(sizeof(char) * (strlen(tmp) + 1));
     5071        strncpy(pixtypename, tmp, strlen(tmp) + 1);
    53275072
    53285073        /* hasnodatavalue */
     
    53335078
    53345079        /* path */
    5335         bandpath = rt_band_get_ext_path(band);
     5080        tmp = rt_band_get_ext_path(band);
     5081        if (tmp) {
     5082                bandpath = palloc(sizeof(char) * (strlen(tmp) + 1));
     5083                strncpy(bandpath, tmp, strlen(tmp) + 1);
     5084        }
    53365085
    53375086        /* isoutdb */
     
    53535102        }
    53545103
    5355         /*
    5356          * generate attribute metadata needed later to produce tuples from raw
    5357          * C strings
    5358          */
    5359         attinmeta = TupleDescGetAttInMetadata(tupdesc);
    5360 
    5361         /*
    5362          * Prepare a values array for building the returned tuple.
    5363          * This should be an array of C strings which will
    5364          * be processed later by the type input functions.
    5365          */
    5366         values = (char **) palloc(values_length * sizeof(char *));
    5367 
    5368         values[0] = (char *) palloc(sizeof(char) * (strlen(pixtypename) + 1));
    5369         values[1] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5370         values[2] = (char *) palloc(sizeof(char) * (MAX_DBL_CHARLEN + 1));
    5371         values[3] = (char *) palloc(sizeof(char) * (MAX_INT_CHARLEN + 1));
    5372         if (bandpath)
    5373                 values[4] = (char *) palloc(sizeof(char) * (strlen(bandpath) + 1));
     5104        BlessTupleDesc(tupdesc);
     5105
     5106        nulls = palloc(sizeof(bool) * values_length);
     5107        for (i = 0; i < values_length; i++) nulls[i] = FALSE;
     5108
     5109        values[0] = CStringGetTextDatum(pixtypename);
     5110        values[1] = BoolGetDatum(hasnodatavalue);
     5111        values[2] = Float8GetDatum(nodatavalue);
     5112        values[3] = BoolGetDatum(isoutdb);
     5113        if (bandpath && strlen(bandpath))
     5114                values[4] = CStringGetTextDatum(bandpath);
    53745115        else
    5375                 values[4] = NULL;
    5376 
    5377         snprintf(
    5378                 values[0],
    5379                 sizeof(char) * (strlen(pixtypename) + 1),
    5380                 "%s",
    5381                 pixtypename
    5382         );
    5383         snprintf(
    5384                 values[1],
    5385                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5386                 "%d",
    5387                 hasnodatavalue
    5388         );
    5389         snprintf(
    5390                 values[2],
    5391                 sizeof(char) * (MAX_DBL_CHARLEN + 1),
    5392                 "%f",
    5393                 nodatavalue
    5394         );
    5395         snprintf(
    5396                 values[3],
    5397                 sizeof(char) * (MAX_INT_CHARLEN + 1),
    5398                 "%d",
    5399                 isoutdb
    5400         );
    5401         if (bandpath) {
    5402                 snprintf(
    5403                         values[4],
    5404                         sizeof(char) * (strlen(bandpath) + 1),
    5405                         "%s",
    5406                         bandpath
    5407                 );
    5408         }
     5116                nulls[4] = TRUE;
    54095117
    54105118        /* build a tuple */
    5411         tuple = BuildTupleFromCStrings(attinmeta, values);
     5119        tuple = heap_form_tuple(tupdesc, values, nulls);
    54125120
    54135121        /* make the tuple into a datum */
     
    54155123
    54165124        /* clean up */
    5417         for (i = 0; i < values_length; i++) {
    5418                 if (NULL != values[i]) pfree(values[i]);
    5419         }
    5420         pfree(values);
     5125        pfree(nulls);
     5126        pfree(pixtypename);
     5127        if (bandpath) pfree(bandpath);
    54215128
    54225129        PG_RETURN_DATUM(result);
  • trunk/raster/rt_pg/rtpostgis.sql.in.c

    r7633 r7638  
    20522052        xr numeric := 0.0;
    20532053    BEGIN
    2054         a := st_scalex(rast);
    2055         d := st_skewy(rast);
    2056         b := st_skewx(rast);
    2057         e := st_scaley(rast);
    2058         c := st_upperleftx(rast);
    2059         f := st_upperlefty(rast);
     2054                                SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast);
    20602055        IF ( b * d - a * e = 0 ) THEN
    20612056            RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0';
     
    20872082        xr numeric := 0.0;
    20882083    BEGIN
    2089         a := st_scalex(rast);
    2090         d := st_skewy(rast);
    2091         b := st_skewx(rast);
    2092         e := st_scaley(rast);
    2093         c := st_upperleftx(rast);
    2094         f := st_upperlefty(rast);
     2084                                SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast);
    20952085        IF ( b * d - a * e = 0 ) THEN
    20962086            RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0';
     
    21412131        yr numeric := 0.0;
    21422132    BEGIN
    2143         a := st_scalex(rast);
    2144         d := st_skewy(rast);
    2145         b := st_skewx(rast);
    2146         e := st_scaley(rast);
    2147         c := st_upperleftx(rast);
    2148         f := st_upperlefty(rast);
     2133                                SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast);
    21492134        IF ( b * d - a * e = 0 ) THEN
    21502135            RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0';
     
    21762161        yr numeric := 0.0;
    21772162    BEGIN
    2178         a := st_scalex(rast);
    2179         d := st_skewy(rast);
    2180         b := st_skewx(rast);
    2181         e := st_scaley(rast);
    2182         c := st_upperleftx(rast);
    2183         f := st_upperlefty(rast);
     2163                                SELECT scalex, skewx, upperleftx, skewy, scaley, upperlefty INTO a, b, c, d, e, f FROM ST_Metadata(rast);
    21842164        IF ( b * d - a * e = 0 ) THEN
    21852165            RAISE EXCEPTION 'Attempting to compute raster coordinate on a raster with scale equal to 0';
     
    22282208        xw numeric := 0.0;
    22292209    BEGIN
    2230         a := st_scalex(rast);
    2231         b := st_skewx(rast);
    2232         c := st_upperleftx(rast);
     2210                                SELECT scalex, skewx, upperleftx INTO a, b, c FROM ST_Metadata(rast);
    22332211        xw := (a::numeric * (xr::numeric - 1.0) + b::numeric * (yr::numeric - 1.0) + c::numeric)::numeric;
    22342212        RETURN xw;
     
    22552233        xw numeric := 0.0;
    22562234    BEGIN
    2257         a := st_scalex(rast);
    2258         b := st_skewx(rast);
    2259         c := st_upperleftx(rast);
     2235                                SELECT scalex, skewx, upperleftx INTO a, b, c FROM ST_Metadata(rast);
    22602236        IF ( b != 0 ) THEN
    22612237            RAISE EXCEPTION 'Attempting to compute raster coordinates on a raster with rotation providing X only. A Y coordinate must also be provided';
     
    22832259        yw numeric := 0.0;
    22842260    BEGIN
    2285         d := st_skewy(rast);
    2286         e := st_scaley(rast);
    2287         f := st_upperlefty(rast);
     2261                                SELECT skewy, scaley, upperlefty INTO d, e, f FROM ST_Metadata(rast);
    22882262        yw := (d::numeric * (xr::numeric - 1.0) + e::numeric * (yr::numeric - 1.0) + f::numeric)::numeric;
    22892263        RETURN yw;
     
    23102284        yw numeric := 0.0;
    23112285    BEGIN
    2312         d := st_skewy(rast);
    2313         e := st_scaley(rast);
    2314         f := st_upperlefty(rast);
     2286                                SELECT skewy, scaley, upperlefty INTO d, e, f FROM ST_Metadata(rast);
    23152287        IF ( d != 0 ) THEN
    23162288            RAISE EXCEPTION 'Attempting to compute raster coordinates on a raster with rotation providing Y only. An X coordinate must also be provided';
  • trunk/raster/test/regress/rt_bandmetadata.sql

    r7357 r7638  
    1 SELECT * FROM ST_BandMetaData(
     1SELECT
     2        pixeltype,
     3        hasnodatavalue,
     4        round(nodatavalue::numeric, 3),
     5        isoutdb,
     6        path
     7FROM ST_BandMetaData(
    28        ST_SetValue(
    39                ST_SetValue(
     
    1420        )
    1521);
    16 SELECT * FROM ST_BandMetaData(
     22SELECT
     23        pixeltype,
     24        hasnodatavalue,
     25        round(nodatavalue::numeric, 3),
     26        isoutdb,
     27        path
     28FROM ST_BandMetaData(
    1729        ST_SetValue(
    1830                ST_SetValue(
     
    3042        1
    3143);
    32 SELECT * FROM ST_BandMetaData(
     44SELECT
     45        pixeltype,
     46        hasnodatavalue,
     47        round(nodatavalue::numeric, 3),
     48        isoutdb,
     49        path
     50FROM ST_BandMetaData(
    3351        ST_SetValue(
    3452                ST_SetValue(
  • trunk/raster/test/regress/rt_bandmetadata_expected

    r7357 r7638  
    1 64BF|t|0|f|
    2 64BF|t|0|f|
     164BF|t|0.000|f|
     264BF|t|0.000|f|
    33NOTICE:  Invalid band index (must use 1-based). Returning NULL
    44||||
  • trunk/raster/test/regress/rt_count.sql

    r7277 r7638  
    9292SELECT ST_Count('test', 'rast');
    9393ROLLBACK;
    94 
Note: See TracChangeset for help on using the changeset viewer.