source: tags/1.5.3/postgis/lwgeom_inout.c

Last change on this file was 5216, checked in by strk, 6 years ago

Backport fix for #411 and #168 (can't check invalidity reason with this version)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
  • Property svn:mime-type set to text/plain
File size: 15.7 KB
Line 
1#include "postgres.h"
2
3#include "../postgis_config.h"
4
5#include <math.h>
6#include <float.h>
7#include <string.h>
8#include <stdio.h>
9#include <errno.h>
10
11#include "access/gist.h"
12#include "access/itup.h"
13
14#include "fmgr.h"
15#include "utils/elog.h"
16# include "lib/stringinfo.h" /* for binary input */
17
18
19#include "liblwgeom.h"
20
21
22
23#include "lwgeom_pg.h"
24#include "profile.h"
25
26void elog_ERROR(const char* string);
27
28
29Datum LWGEOM_in(PG_FUNCTION_ARGS);
30Datum LWGEOM_out(PG_FUNCTION_ARGS);
31Datum LWGEOM_to_text(PG_FUNCTION_ARGS);
32Datum LWGEOM_to_bytea(PG_FUNCTION_ARGS);
33Datum LWGEOM_from_bytea(PG_FUNCTION_ARGS);
34Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS);
35Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS);
36Datum LWGEOM_recv(PG_FUNCTION_ARGS);
37Datum LWGEOM_send(PG_FUNCTION_ARGS);
38Datum BOOL_to_text(PG_FUNCTION_ARGS);
39
40
41/*
42 *  included here so we can be independent from postgis
43 * WKB structure  -- exactly the same as TEXT
44 */
45typedef struct Well_known_bin
46{
47        int32 size;             /* total size of this structure */
48        uchar  data[1]; /* THIS HOLD VARIABLE LENGTH DATA */
49}
50WellKnownBinary;
51
52
53/*
54 * LWGEOM_in(cstring)
55 * format is '[SRID=#;]wkt|wkb'
56 *  LWGEOM_in( 'SRID=99;POINT(0 0)')
57 *  LWGEOM_in( 'POINT(0 0)')            --> assumes SRID=-1
58 *  LWGEOM_in( 'SRID=99;0101000000000000000000F03F000000000000004')
59 *  returns a PG_LWGEOM object
60 */
61PG_FUNCTION_INFO_V1(LWGEOM_in);
62Datum LWGEOM_in(PG_FUNCTION_ARGS)
63{
64        char *str = PG_GETARG_CSTRING(0);
65        LWGEOM_PARSER_RESULT lwg_parser_result;
66        LWGEOM *lwgeom;
67        PG_LWGEOM *ret;
68        int result;
69
70        /* will handle both HEXEWKB and EWKT */
71        result = serialized_lwgeom_from_ewkt(&lwg_parser_result, str, PARSER_CHECK_ALL);
72        if (result)
73                PG_PARSER_ERROR(lwg_parser_result);
74
75        lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);
76
77        ret = pglwgeom_serialize(lwgeom);
78        lwgeom_release(lwgeom);
79
80        if ( is_worth_caching_pglwgeom_bbox(ret) )
81        {
82                ret = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
83                                                       LWGEOM_addBBOX, PointerGetDatum(ret)));
84        }
85
86        PG_RETURN_POINTER(ret);
87}
88
89/*
90 * LWGEOM_out(lwgeom) --> cstring
91 * output is 'SRID=#;<wkb in hex form>'
92 * ie. 'SRID=-99;0101000000000000000000F03F0000000000000040'
93 * WKB is machine endian
94 * if SRID=-1, the 'SRID=-1;' will probably not be present.
95 */
96PG_FUNCTION_INFO_V1(LWGEOM_out);
97Datum LWGEOM_out(PG_FUNCTION_ARGS)
98{
99        LWGEOM_UNPARSER_RESULT lwg_unparser_result;
100        PG_LWGEOM *lwgeom;
101        int result;
102
103        lwgeom = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
104        result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_NONE, -1);
105        if (result)
106                PG_UNPARSER_ERROR(lwg_unparser_result);
107
108        PG_RETURN_CSTRING(lwg_unparser_result.wkoutput);
109}
110
111/*
112 * AsHEXEWKB(geom, string)
113 */
114PG_FUNCTION_INFO_V1(LWGEOM_asHEXEWKB);
115Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS)
116{
117        LWGEOM_UNPARSER_RESULT lwg_unparser_result;
118        PG_LWGEOM *lwgeom;
119        int result;
120        text *text_result;
121        text *type;
122        unsigned int byteorder=-1;
123
124        lwgeom = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
125
126        if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
127        {
128                type = PG_GETARG_TEXT_P(1);
129                if (VARSIZE(type) < 7)
130                {
131                        elog(ERROR,"AsHEXEWKB(geometry, <type>) - type should be 'XDR' or 'NDR'.  type length is %i",VARSIZE(type) -VARHDRSZ);
132                        PG_RETURN_NULL();
133                }
134
135                if  ( ! strncmp(VARDATA(type), "xdr", 3) ||
136                        ! strncmp(VARDATA(type), "XDR", 3) )
137                {
138                        byteorder = XDR;
139                }
140                else
141                {
142                        byteorder = NDR;
143                }
144        }
145
146        result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_NONE, byteorder);
147        if (result)
148                PG_UNPARSER_ERROR(lwg_unparser_result);
149
150        text_result = palloc(lwg_unparser_result.size+VARHDRSZ);
151        memcpy(VARDATA(text_result),lwg_unparser_result.wkoutput,lwg_unparser_result.size);
152        SET_VARSIZE(text_result, lwg_unparser_result.size+VARHDRSZ);
153        pfree(lwg_unparser_result.wkoutput);
154
155        PG_RETURN_POINTER(text_result);
156
157}
158
159/*
160 * LWGEOM_to_text(lwgeom) --> text
161 * output is 'SRID=#;<wkb in hex form>'
162 * ie. 'SRID=-99;0101000000000000000000F03F0000000000000040'
163 * WKB is machine endian
164 * if SRID=-1, the 'SRID=-1;' will probably not be present.
165 */
166PG_FUNCTION_INFO_V1(LWGEOM_to_text);
167Datum LWGEOM_to_text(PG_FUNCTION_ARGS)
168{
169        LWGEOM_UNPARSER_RESULT lwg_unparser_result;
170        PG_LWGEOM *lwgeom;
171        int result;
172        text *text_result;
173
174        lwgeom = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
175        result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom), PARSER_CHECK_NONE, -1);
176        if (result)
177                PG_UNPARSER_ERROR(lwg_unparser_result);
178
179        text_result = palloc(lwg_unparser_result.size+VARHDRSZ);
180        memcpy(VARDATA(text_result),lwg_unparser_result.wkoutput,lwg_unparser_result.size);
181        SET_VARSIZE(text_result, lwg_unparser_result.size+VARHDRSZ);
182        pfree(lwg_unparser_result.wkoutput);
183
184        PG_RETURN_POINTER(text_result);
185}
186
187/*
188 * LWGEOMFromWKB(wkb,  [SRID] )
189 * NOTE: wkb is in *binary* not hex form.
190 *
191 * NOTE: this function parses EWKB (extended form)
192 *       which also contains SRID info. When the SRID
193 *       argument is provided it will override any SRID
194 *       info found in EWKB format.
195 *
196 * NOTE: this function is *unoptimized* as will copy
197 *       the object when adding SRID and when adding BBOX.
198 *       additionally, it suffers from the non-optimal
199 *       pglwgeom_from_ewkb function.
200 *
201 */
202PG_FUNCTION_INFO_V1(LWGEOMFromWKB);
203Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
204{
205        WellKnownBinary *wkb_input;
206        PG_LWGEOM *lwgeom, *lwgeom2;
207
208        wkb_input = (WellKnownBinary *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
209
210        lwgeom2 = pglwgeom_from_ewkb((uchar *)VARDATA(wkb_input), PARSER_CHECK_ALL,
211                                     VARSIZE(wkb_input)-VARHDRSZ);
212
213        if (  ( PG_NARGS()>1) && ( ! PG_ARGISNULL(1) ))
214        {
215                lwgeom = pglwgeom_setSRID(lwgeom2, PG_GETARG_INT32(1));
216                lwfree(lwgeom2);
217        }
218        else lwgeom = lwgeom2;
219
220        if ( is_worth_caching_pglwgeom_bbox(lwgeom) )
221        {
222                lwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
223                                                          LWGEOM_addBBOX, PointerGetDatum(lwgeom)));
224        }
225
226        PG_RETURN_POINTER(lwgeom);
227}
228
229/*
230 * WKBFromLWGEOM(lwgeom) --> wkb
231 * this will have no 'SRID=#;'
232 */
233PG_FUNCTION_INFO_V1(WKBFromLWGEOM);
234Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
235{
236        /* #define BINARY_FROM_HEX 1 */
237
238        LWGEOM_UNPARSER_RESULT lwg_unparser_result;
239        PG_LWGEOM *lwgeom_input; /* SRID=#;<hexized wkb> */
240        char *lwgeom_result;
241        int result;
242        int size_result;
243#ifdef BINARY_FROM_HEX
244        char *hexized_wkb; /* hexized_wkb_srid w/o srid */
245        char *semicolonLoc;
246        int t;
247#endif /* BINARY_FROM_HEX */
248        text *type;
249        unsigned int byteorder=-1;
250
251        PROFSTART(PROF_QRUN);
252
253        if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
254        {
255                type = PG_GETARG_TEXT_P(1);
256                if (VARSIZE(type) < 7)
257                {
258                        elog(ERROR,"asbinary(geometry, <type>) - type should be 'XDR' or 'NDR'.  type length is %i",VARSIZE(type) -VARHDRSZ);
259                        PG_RETURN_NULL();
260                }
261
262                if  ( ! strncmp(VARDATA(type), "xdr", 3) ||
263                        ! strncmp(VARDATA(type), "XDR", 3) )
264                {
265                        byteorder = XDR;
266                }
267                else
268                {
269                        byteorder = NDR;
270                }
271        }
272
273        lwgeom_input = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
274
275#ifdef BINARY_FROM_HEX
276        result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom_input), byteorder);
277        if (result)
278                PG_UNPARSER_ERROR(lwg_unparser_result);
279
280        LWDEBUGF(3, "in WKBFromLWGEOM with WKB = '%s'", lwg_unparser_result.wkoutput);
281
282        hexized_wkb_srid = lwg_unparser_result.wkoutput;
283
284        semicolonLoc = strchr(lwg_unparser_result.wkoutput,';');
285        if (semicolonLoc != NULL)
286        {
287                hexized_wkb = (semicolonLoc+1);
288        }
289
290        LWDEBUGF(3, "in WKBFromLWGEOM with WKB (with no 'SRID=#;' = '%s'",
291                 hexized_wkb);
292
293        size_result = lwg_unparser_result.size/2 + VARHDRSZ;
294        lwgeom_result = palloc(size_result);
295        SET_VARSIZE(lwgeom_result, size_result);
296
297        /* have a hexized string, want to make it binary */
298        for (t=0; t< (lwgeom_unparser_result.size/2); t++)
299        {
300                ((uchar *) VARDATA(lwgeom_result))[t] = parse_hex(  hexized_wkb + (t*2) );
301        }
302
303        pfree(hexized_wkb);
304
305#else /* ndef BINARY_FROM_HEX */
306
307        result = serialized_lwgeom_to_ewkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom_input), PARSER_CHECK_ALL, byteorder);
308        if (result)
309                PG_UNPARSER_ERROR(lwg_unparser_result);
310
311        size_result = lwg_unparser_result.size+VARHDRSZ;
312        lwgeom_result = palloc(size_result);
313        SET_VARSIZE(lwgeom_result, size_result);
314        memcpy(VARDATA(lwgeom_result), lwg_unparser_result.wkoutput, lwg_unparser_result.size);
315        pfree(lwg_unparser_result.wkoutput);
316
317#endif
318
319#if POSTGIS_PROFILE > 0
320        PROFSTOP(PROF_QRUN);
321        lwnotice("serialized_lwgeom_to_ewkb: prof: %lu", proftime[PROF_QRUN]);
322#endif
323
324        LWDEBUGF(3, "Output size is %lu (comp: %lu)",
325                 VARSIZE(lwgeom_result), (unsigned long)size_result);
326
327        PG_RETURN_POINTER(lwgeom_result);
328}
329
330/* puts a bbox inside the geometry */
331PG_FUNCTION_INFO_V1(LWGEOM_addBBOX);
332Datum LWGEOM_addBBOX(PG_FUNCTION_ARGS)
333{
334        PG_LWGEOM *lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
335        PG_LWGEOM *result;
336        BOX2DFLOAT4     box;
337        uchar   old_type;
338        int             size;
339
340        POSTGIS_DEBUG(2, "in LWGEOM_addBBOX");
341
342        if (lwgeom_hasBBOX( lwgeom->type ) )
343        {
344                POSTGIS_DEBUG(3, "LWGEOM_addBBOX  -- already has bbox");
345
346                /* easy - already has one.  Just copy! */
347                result = palloc (VARSIZE(lwgeom));
348                SET_VARSIZE(result, VARSIZE(lwgeom));
349                memcpy(VARDATA(result), VARDATA(lwgeom), VARSIZE(lwgeom)-VARHDRSZ);
350                PG_RETURN_POINTER(result);
351        }
352
353        POSTGIS_DEBUG(3, "LWGEOM_addBBOX  -- giving it a bbox");
354
355        /* construct new one */
356        if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), &box) )
357        {
358                /* Empty geom, no bbox to add */
359                result = palloc (VARSIZE(lwgeom));
360                SET_VARSIZE(result, VARSIZE(lwgeom));
361                memcpy(VARDATA(result), VARDATA(lwgeom), VARSIZE(lwgeom)-VARHDRSZ);
362                PG_RETURN_POINTER(result);
363        }
364        old_type = lwgeom->type;
365
366        size = VARSIZE(lwgeom)+sizeof(BOX2DFLOAT4);
367
368        result = palloc(size); /* 16 for bbox2d */
369        SET_VARSIZE(result, size);
370
371        result->type = lwgeom_makeType_full(
372                           TYPE_HASZ(old_type),
373                           TYPE_HASM(old_type),
374                           lwgeom_hasSRID(old_type), lwgeom_getType(old_type), 1);
375
376        /* copy in bbox */
377        memcpy(result->data, &box, sizeof(BOX2DFLOAT4));
378
379        POSTGIS_DEBUGF(3, "result->type hasbbox: %d", TYPE_HASBBOX(result->type));
380        POSTGIS_DEBUG(3, "LWGEOM_addBBOX  -- about to copy serialized form");
381
382        /* everything but the type and length */
383        memcpy((char *)VARDATA(result)+sizeof(BOX2DFLOAT4)+1, (char *)VARDATA(lwgeom)+1, VARSIZE(lwgeom)-VARHDRSZ-1);
384
385        PG_RETURN_POINTER(result);
386}
387
388char
389is_worth_caching_pglwgeom_bbox(const PG_LWGEOM *in)
390{
391#if ! POSTGIS_AUTOCACHE_BBOX
392        return false;
393#endif
394        if ( TYPE_GETTYPE(in->type) == POINTTYPE ) return false;
395        return true;
396}
397
398char
399is_worth_caching_serialized_bbox(const uchar *in)
400{
401#if ! POSTGIS_AUTOCACHE_BBOX
402        return false;
403#endif
404        if ( TYPE_GETTYPE((uchar)in[0]) == POINTTYPE ) return false;
405        return true;
406}
407
408char
409is_worth_caching_lwgeom_bbox(const LWGEOM *in)
410{
411#if ! POSTGIS_AUTOCACHE_BBOX
412        return false;
413#endif
414        if ( TYPE_GETTYPE(in->type) == POINTTYPE ) return false;
415        return true;
416}
417
418/* removes a bbox from a geometry */
419PG_FUNCTION_INFO_V1(LWGEOM_dropBBOX);
420Datum LWGEOM_dropBBOX(PG_FUNCTION_ARGS)
421{
422        PG_LWGEOM *lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
423        PG_LWGEOM *result;
424        uchar old_type;
425        int size;
426
427        POSTGIS_DEBUG(2, "in LWGEOM_dropBBOX");
428
429        if (!lwgeom_hasBBOX( lwgeom->type ) )
430        {
431                POSTGIS_DEBUG(3, "LWGEOM_dropBBOX  -- doesnt have a bbox already");
432
433                result = palloc (VARSIZE(lwgeom));
434                SET_VARSIZE(result, VARSIZE(lwgeom));
435                memcpy(VARDATA(result), VARDATA(lwgeom), VARSIZE(lwgeom)-VARHDRSZ);
436                PG_RETURN_POINTER(result);
437        }
438
439        POSTGIS_DEBUG(3, "LWGEOM_dropBBOX  -- dropping the bbox");
440
441        /* construct new one */
442        old_type = lwgeom->type;
443
444        size = VARSIZE(lwgeom)-sizeof(BOX2DFLOAT4);
445
446        result = palloc(size); /* 16 for bbox2d */
447        SET_VARSIZE(result, size);
448
449        result->type = lwgeom_makeType_full(
450                           TYPE_HASZ(old_type),
451                           TYPE_HASM(old_type),
452                           lwgeom_hasSRID(old_type), lwgeom_getType(old_type), 0);
453
454        /* everything but the type and length */
455        memcpy((char *)VARDATA(result)+1, ((char *)(lwgeom->data))+sizeof(BOX2DFLOAT4), size-VARHDRSZ-1);
456
457        PG_RETURN_POINTER(result);
458}
459
460
461/* for the wkt parser */
462void elog_ERROR(const char* string)
463{
464        elog(ERROR, "%s", string);
465}
466
467/*
468 * parse WKT input
469 * parse_WKT_lwgeom(TEXT) -> LWGEOM
470 */
471PG_FUNCTION_INFO_V1(parse_WKT_lwgeom);
472Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS)
473{
474        /* text */
475        text *wkt_input = PG_GETARG_TEXT_P(0);
476        PG_LWGEOM *ret;  /*with length */
477        LWGEOM_PARSER_RESULT lwg_parser_result;
478        LWGEOM *lwgeom;
479        char *wkt;
480        int wkt_size, result;
481
482        wkt_size = VARSIZE(wkt_input)-VARHDRSZ; /* actual letters */
483
484        wkt = palloc( wkt_size+1); /* +1 for null */
485        memcpy(wkt, VARDATA(wkt_input), wkt_size );
486        wkt[wkt_size] = 0; /* null term */
487
488
489        POSTGIS_DEBUGF(3, "in parse_WKT_lwgeom with input: '%s'",wkt);
490
491        result = serialized_lwgeom_from_ewkt(&lwg_parser_result, wkt, PARSER_CHECK_ALL);
492        if (result)
493                PG_PARSER_ERROR(lwg_parser_result);
494
495        lwgeom = lwgeom_deserialize(lwg_parser_result.serialized_lwgeom);
496
497        ret = pglwgeom_serialize(lwgeom);
498        lwgeom_release(lwgeom);
499
500        POSTGIS_DEBUG(3, "parse_WKT_lwgeom:: finished parse");
501
502        pfree (wkt);
503
504        if (ret == NULL) elog(ERROR,"parse_WKT:: couldnt parse!");
505
506        if ( is_worth_caching_pglwgeom_bbox(ret) )
507        {
508                ret = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
509                                                       LWGEOM_addBBOX, PointerGetDatum(ret)));
510        }
511
512        PG_RETURN_POINTER(ret);
513}
514
515
516/*
517 * This function must advance the StringInfo.cursor pointer
518 * and leave it at the end of StringInfo.buf. If it fails
519 * to do so the backend will raise an exception with message:
520 * ERROR:  incorrect binary data format in bind parameter #
521 *
522 */
523PG_FUNCTION_INFO_V1(LWGEOM_recv);
524Datum LWGEOM_recv(PG_FUNCTION_ARGS)
525{
526        StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
527        bytea *wkb;
528        PG_LWGEOM *lwgeom_result;
529#if POSTGIS_DEBUG_LEVEL > 0
530        int result;
531        LWGEOM_UNPARSER_RESULT lwg_unparser_result;
532#endif
533
534        POSTGIS_DEBUG(2, "LWGEOM_recv start");
535
536        /* Add VARLENA size info to make it a valid varlena object */
537        wkb = (bytea *)palloc(buf->len+VARHDRSZ);
538        SET_VARSIZE(wkb, buf->len+VARHDRSZ);
539        memcpy(VARDATA(wkb), buf->data, buf->len);
540
541        POSTGIS_DEBUG(3, "LWGEOM_recv calling LWGEOMFromWKB");
542
543        /* Call LWGEOM_from_bytea function... */
544        lwgeom_result = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
545                            LWGEOMFromWKB, PointerGetDatum(wkb)));
546
547        POSTGIS_DEBUG(3, "LWGEOM_recv advancing StringInfo buffer");
548
549#if POSTGIS_DEBUG_LEVEL > 0
550        result = serialized_lwgeom_to_hexwkb(&lwg_unparser_result, SERIALIZED_FORM(lwgeom_result), PARSER_CHECK_NONE, -1);
551        POSTGIS_DEBUGF(3, "LWGEOM_from_bytea returned %s", lwg_unparser_result.wkoutput);
552#endif
553
554        /* Set cursor to the end of buffer (so the backend is happy) */
555        buf->cursor = buf->len;
556
557        POSTGIS_DEBUG(3, "LWGEOM_recv returning");
558
559        PG_RETURN_POINTER(lwgeom_result);
560}
561
562PG_FUNCTION_INFO_V1(LWGEOM_send);
563Datum LWGEOM_send(PG_FUNCTION_ARGS)
564{
565        bytea *result;
566
567        POSTGIS_DEBUG(2, "LWGEOM_send called");
568
569        result = (bytea *)DatumGetPointer(DirectFunctionCall1(
570                                              WKBFromLWGEOM, PG_GETARG_DATUM(0)));
571
572        PG_RETURN_POINTER(result);
573}
574
575PG_FUNCTION_INFO_V1(LWGEOM_to_bytea);
576Datum LWGEOM_to_bytea(PG_FUNCTION_ARGS)
577{
578        bytea *result;
579
580        POSTGIS_DEBUG(2, "LWGEOM_to_bytea called");
581
582        result = (bytea *)DatumGetPointer(DirectFunctionCall1(
583                                              WKBFromLWGEOM, PG_GETARG_DATUM(0)));
584
585        PG_RETURN_POINTER(result);
586}
587
588PG_FUNCTION_INFO_V1(LWGEOM_from_bytea);
589Datum LWGEOM_from_bytea(PG_FUNCTION_ARGS)
590{
591        PG_LWGEOM *result;
592
593        POSTGIS_DEBUG(2, "LWGEOM_from_bytea start");
594
595        result = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1(
596                                                  LWGEOMFromWKB, PG_GETARG_DATUM(0)));
597
598        PG_RETURN_POINTER(result);
599}
600
601PG_FUNCTION_INFO_V1(BOOL_to_text);
602Datum BOOL_to_text(PG_FUNCTION_ARGS)
603{
604        bool b = PG_GETARG_BOOL(0);
605        char c;
606        text *result;
607
608        c = b ? 't' : 'f';
609
610        result = palloc(VARHDRSZ+1*sizeof(char));
611        SET_VARSIZE(result, VARHDRSZ+1*sizeof(char));
612        memcpy(VARDATA(result), &c, 1*sizeof(char));
613
614        PG_RETURN_POINTER(result);
615
616}
Note: See TracBrowser for help on using the repository browser.