28 #include "../postgis_config.h"
36 #include "utils/elog.h"
37 #include "utils/array.h"
38 #include "utils/builtins.h"
39 #include "lib/stringinfo.h"
40 #include "catalog/pg_type.h"
43 #include "lwgeom_pg.h"
45 #include "lwgeom_transform.h"
66 int32 typmod = PG_GETARG_INT32(0);
72 POSTGIS_DEBUGF(3,
"Got typmod(srid = %d, type = %d, hasz = %d, hasm = %d)", srid,
type, hasz, hasm);
75 if (!(srid ||
type || hasz || hasm) || typmod < 0)
77 PG_RETURN_CSTRING(pstrdup(
""));
82 appendStringInfoChar(&si,
'(');
87 else if (srid || hasz || hasm)
88 appendStringInfoString(&si,
"Geometry");
91 if (hasz) appendStringInfoString(&si,
"Z");
94 if (hasm) appendStringInfoString(&si,
"M");
97 if (srid) appendStringInfo(&si,
",%d", srid);
100 appendStringInfoChar(&si,
')');
102 PG_RETURN_CSTRING(si.data);
121 POSTGIS_DEBUG(2,
"Entered function");
124 if (typmod < 0)
return gser;
126 POSTGIS_DEBUGF(3,
"Got geom(type = %d, srid = %d, hasz = %d, hasm = %d)", geom_type, geom_srid, geom_z, geom_m);
127 POSTGIS_DEBUGF(3,
"Got typmod(type = %d, srid = %d, hasz = %d, hasm = %d)", typmod_type, typmod_srid, typmod_z, typmod_m);
151 if ( typmod_srid > 0 && geom_srid == 0 )
154 geom_srid = typmod_srid;
158 if ( typmod_srid > 0 && typmod_srid != geom_srid )
161 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
162 errmsg(
"Geometry SRID (%d) does not match column SRID (%d)", geom_srid, typmod_srid) ));
173 geography_serialize(mgeom) :
174 geometry_serialize(mgeom);
183 if ( typmod_type > 0 &&
190 (typmod_type != geom_type)) )
193 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
194 errmsg(
"Geometry type (%s) does not match column type (%s)",
lwtype_name(geom_type),
lwtype_name(typmod_type)) ));
198 if ( typmod_z && ! geom_z )
201 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
202 errmsg(
"Column has Z dimension but geometry does not" )));
206 if ( geom_z && ! typmod_z )
209 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
210 errmsg(
"Geometry has Z dimension but column does not" )));
214 if ( typmod_m && ! geom_m )
217 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
218 errmsg(
"Column has M dimension but geometry does not" )));
222 if ( geom_m && ! typmod_m )
225 errcode(ERRCODE_INVALID_PARAMETER_VALUE),
226 errmsg(
"Geometry has M dimension but column does not" )));
241 if (ARR_ELEMTYPE(arr) != CSTRINGOID)
243 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
244 errmsg(
"typmod array must be type cstring[]")));
246 if (ARR_NDIM(arr) != 1)
248 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
249 errmsg(
"typmod array must be one-dimensional")));
251 if (ARR_HASNULL(arr))
253 (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
254 errmsg(
"typmod array must not contain nulls")));
256 deconstruct_array(arr,
257 CSTRINGOID, -2,
false,
'c',
258 &elem_values, NULL, &n);
266 for (i = 0; i < n; i++)
270 char *
s = DatumGetCString(elem_values[i]);
278 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
279 errmsg(
"Invalid geometry type modifier: %s",
s)));
292 char *int_string = DatumGetCString(elem_values[i]);
298 l = strtol(int_string, &endp, 10);
300 if (int_string == endp)
302 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
303 errmsg(
"invalid input syntax for type %s: \"%s\"",
304 "integer", int_string)));
306 if (errno == ERANGE || l < INT_MIN || l > INT_MAX)
308 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
309 errmsg(
"value \"%s\" is out of range for type %s", int_string,
314 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
315 errmsg(
"invalid input syntax for type %s: \"%s\"",
316 "integer", int_string)));
319 POSTGIS_DEBUGF(3,
"srid: %d", srid);
340 ArrayType *arr = (ArrayType *) DatumGetPointer(PG_GETARG_DATUM(0));
344 srid_check_latlong(srid);
346 PG_RETURN_INT32(typmod);
357 ArrayType *arr = (ArrayType *) DatumGetPointer(PG_GETARG_DATUM(0));
359 PG_RETURN_INT32(typmod);
371 int32 typmod = PG_GETARG_INT32(1);
378 PG_RETURN_POINTER(arg);
390 int32 typmod = PG_GETARG_INT32(1);
397 PG_RETURN_POINTER(arg);
408 int32 typmod = PG_GETARG_INT32(0);
410 char *
s = (
char*)palloc(64);
415 if ( typmod < 0 ||
type == 0 )
416 ptr += sprintf(ptr,
"Geometry");
422 ptr += sprintf(ptr,
"%s",
"Z");
426 ptr += sprintf(ptr,
"%s",
"M");
428 stext = cstring_to_text(
s);
430 PG_RETURN_TEXT_P(stext);
440 int32 typmod = PG_GETARG_INT32(0);
448 PG_RETURN_INT32(dims);
458 int32 typmod = PG_GETARG_INT32(0);
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
int gserialized_is_geodetic(const GSERIALIZED *g)
Check if a GSERIALIZED is a geography.
int gserialized_has_m(const GSERIALIZED *g)
Check if a GSERIALIZED has an M ordinate.
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
void gserialized_set_srid(GSERIALIZED *g, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function).
int gserialized_has_z(const GSERIALIZED *g)
Check if a GSERIALIZED has a Z ordinate.
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Datum geometry_enforce_typmod(PG_FUNCTION_ARGS)
Datum postgis_typmod_type(PG_FUNCTION_ARGS)
Datum geography_typmod_in(PG_FUNCTION_ARGS)
Datum geometry_typmod_in(PG_FUNCTION_ARGS)
Datum postgis_typmod_dims(PG_FUNCTION_ARGS)
Datum geography_enforce_typmod(PG_FUNCTION_ARGS)
GSERIALIZED * postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod)
Check the consistency of the metadata we want to enforce in the typmod: srid, type and dimensionality...
static uint32 gserialized_typmod_in(ArrayType *arr, int is_geography)
Datum postgis_typmod_srid(PG_FUNCTION_ARGS)
Datum postgis_typmod_out(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(postgis_typmod_out)
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
#define TYPMOD_GET_SRID(typmod)
Macros for manipulating the 'typemod' int.
#define TYPMOD_SET_SRID(typmod, srid)
void lwgeom_free(LWGEOM *geom)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
int geometry_type_from_string(const char *str, uint8_t *type, int *z, int *m)
Utility function to get type number from string.
#define TYPMOD_GET_M(typmod)
#define TYPMOD_SET_TYPE(typmod, type)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
uint8_t lwtype_multitype(uint8_t type)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
#define TYPMOD_GET_TYPE(typmod)
#define TYPMOD_SET_M(typmod)
#define LW_TRUE
Return types for functions with status returns.
#define SRID_UNKNOWN
Unknown SRID value.
#define TYPMOD_SET_Z(typmod)
#define TYPMOD_GET_Z(typmod)
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
This library is the generic geometry handling section of PostGIS.