/* Return a specific normalized UR coordinate */ Datum cube_ur_coord(PG_FUNCTION_ARGS) { NDBOX *c = PG_GETARG_NDBOX(0); int n = PG_GETARG_INT16(1); double result; if (c->dim >= n && n > 0) result = Max(c->x[n - 1], c->x[c->dim + n - 1]); else result = 0; PG_FREE_IF_COPY(c, 0); PG_RETURN_FLOAT8(result); }
/* Return a specific normalized UR coordinate */ Datum cube_ur_coord(PG_FUNCTION_ARGS) { NDBOX *c = PG_GETARG_NDBOX(0); int n = PG_GETARG_INT16(1); double result; if (DIM(c) >= n && n > 0) result = Max(LL_COORD(c, n - 1), UR_COORD(c, n - 1)); else result = 0; PG_FREE_IF_COPY(c, 0); PG_RETURN_FLOAT8(result); }
Datum text2ltree(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_PP(0); char *s; ltree *out; s = text_to_cstring(in); out = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in, PointerGetDatum(s))); pfree(s); PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); }
Datum ltree_addtext(PG_FUNCTION_ARGS) { ltree *a = PG_GETARG_LTREE(0); text *b = PG_GETARG_TEXT_PP(1); char *s; ltree *r, *tmp; s = text_to_cstring(b); tmp = (ltree *) DatumGetPointer(DirectFunctionCall1(ltree_in, PointerGetDatum(s))); pfree(s); r = ltree_concat(a, tmp); pfree(tmp); PG_FREE_IF_COPY(a, 0); PG_FREE_IF_COPY(b, 1); PG_RETURN_POINTER(r); }
Datum parse_byname(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; Datum result; SET_FUNCOID(); if (SRF_IS_FIRSTCALL()) { text *name = PG_GETARG_TEXT_P(0); text *txt = PG_GETARG_TEXT_P(1); funcctx = SRF_FIRSTCALL_INIT(); prs_setup_firstcall(fcinfo, funcctx, name2id_prs(name), txt); PG_FREE_IF_COPY(name, 0); PG_FREE_IF_COPY(txt, 1); } funcctx = SRF_PERCALL_SETUP(); if ((result = prs_process_call(funcctx)) != (Datum) 0) SRF_RETURN_NEXT(funcctx, result); SRF_RETURN_DONE(funcctx); }
/* cube_size */ Datum cube_size(PG_FUNCTION_ARGS) { NDBOX *a = PG_GETARG_NDBOX(0); double result; int i, j; result = 1.0; for (i = 0, j = a->dim; i < a->dim; i++, j++) result = result * Abs((a->x[j] - a->x[i])); PG_FREE_IF_COPY(a, 0); PG_RETURN_FLOAT8(result); }
Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); GBOX gbox; if ( gserialized_get_gbox_p(geom, &gbox) == LW_FAILURE ) PG_RETURN_NULL(); /* Strip out higher dimensions */ FLAGS_SET_Z(gbox.flags, 0); FLAGS_SET_M(gbox.flags, 0); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(gbox_copy(&gbox)); }
Datum show_trgm(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_P(0); TRGM *trg; Datum *d; ArrayType *a; trgm *ptr; int i; trg = generate_trgm(VARDATA(in), VARSIZE(in) - VARHDRSZ); d = (Datum *) palloc(sizeof(Datum) * (1 + ARRNELEM(trg))); for (i = 0, ptr = GETARR(trg); i < ARRNELEM(trg); i++, ptr++) { text *item = (text *) palloc(VARHDRSZ + Max(12, pg_database_encoding_max_length() * 3)); if (pg_database_encoding_max_length() > 1 && !ISPRINTABLETRGM(ptr)) { snprintf(VARDATA(item), 12, "0x%06x", trgm2int(ptr)); SET_VARSIZE(item, VARHDRSZ + strlen(VARDATA(item))); } else { SET_VARSIZE(item, VARHDRSZ + 3); CPTRGM(VARDATA(item), ptr); } d[i] = PointerGetDatum(item); } a = construct_array( d, ARRNELEM(trg), TEXTOID, -1, false, 'i' ); for (i = 0; i < ARRNELEM(trg); i++) pfree(DatumGetPointer(d[i])); pfree(d); pfree(trg); PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(a); }
/* Test if a box is also a point */ Datum cube_is_point(PG_FUNCTION_ARGS) { NDBOX *a = PG_GETARG_NDBOX(0); int i, j; for (i = 0, j = a->dim; i < a->dim; i++, j++) { if (a->x[i] != a->x[j]) PG_RETURN_BOOL(FALSE); } PG_FREE_IF_COPY(a, 0); PG_RETURN_BOOL(TRUE); }
Datum citext_hash(PG_FUNCTION_ARGS) { text *txt = PG_GETARG_TEXT_PP(0); char *str; Datum result; str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt)); result = hash_any((unsigned char *) str, strlen(str)); pfree(str); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(txt, 0); PG_RETURN_DATUM(result); }
Datum sfcgal_is_solid(PG_FUNCTION_ARGS) { int result; GSERIALIZED *input = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom = lwgeom_from_gserialized(input); PG_FREE_IF_COPY(input, 0); if (! lwgeom) { lwerror("sfcgal_is_solid: Unable to deserialize input"); } result = FLAGS_GET_SOLID( lwgeom->flags ); lwgeom_free(lwgeom); PG_RETURN_BOOL(result); }
Datum jsquery_hash(PG_FUNCTION_ARGS) { JsQuery *jq = PG_GETARG_JSQUERY(0); JsQueryItem v; pg_crc32 res; INIT_CRC32(res); jsqInit(&v, jq); hashJsQuery(&v, &res); FIN_CRC32(res); PG_FREE_IF_COPY(jq, 0); PG_RETURN_INT32(res); }
Datum geography_from_geometry(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = NULL; GSERIALIZED *g_ser = NULL; geography_valid_type(gserialized_get_type(geom)); lwgeom = lwgeom_from_gserialized(geom); /* Force default SRID */ if ( (int)lwgeom->srid <= 0 ) { lwgeom->srid = SRID_DEFAULT; } /* Error on any SRID != default */ srid_is_latlong(fcinfo, lwgeom->srid); /* Force the geometry to have valid geodetic coordinate range. */ lwgeom_nudge_geodetic(lwgeom); if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE ) { ereport(NOTICE, ( errmsg_internal("Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" )) ); } /* ** Serialize our lwgeom and set the geodetic flag so subsequent ** functions do the right thing. */ lwgeom_set_geodetic(lwgeom, true); /* Recalculate the boxes after re-setting the geodetic bit */ lwgeom_drop_bbox(lwgeom); lwgeom_add_bbox(lwgeom); g_ser = geography_serialize(lwgeom); /* ** Replace the unaligned lwgeom with a new aligned one based on GSERIALIZED. */ lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(g_ser); }
/* Add a dimension to an existing cube */ Datum cube_c_f8_f8(PG_FUNCTION_ARGS) { NDBOX *cube = PG_GETARG_NDBOX(0); double x1 = PG_GETARG_FLOAT8(1); double x2 = PG_GETARG_FLOAT8(2); NDBOX *result; int size; int i; if (DIM(cube) + 1 > CUBE_MAX_DIM) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("can't extend cube"), errdetail("A cube cannot have more than %d dimensions.", CUBE_MAX_DIM))); if (IS_POINT(cube) && (x1 == x2)) { size = POINT_SIZE((DIM(cube) + 1)); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, DIM(cube) + 1); SET_POINT_BIT(result); for (i = 0; i < DIM(cube); i++) result->x[i] = cube->x[i]; result->x[DIM(result) - 1] = x1; } else { size = CUBE_SIZE((DIM(cube) + 1)); result = (NDBOX *) palloc0(size); SET_VARSIZE(result, size); SET_DIM(result, DIM(cube) + 1); for (i = 0; i < DIM(cube); i++) { result->x[i] = LL_COORD(cube, i); result->x[DIM(result) + i] = UR_COORD(cube, i); } result->x[DIM(result) - 1] = x1; result->x[2 * DIM(result) - 1] = x2; } PG_FREE_IF_COPY(cube, 0); PG_RETURN_NDBOX(result); }
Datum cube_subset(PG_FUNCTION_ARGS) { NDBOX *c, *result; ArrayType *idx; int size, dim, i; int *dx; c = PG_GETARG_NDBOX(0); idx = (ArrayType *) PG_GETARG_VARLENA_P(1); if (ARR_HASNULL(idx)) { ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("Cannot work with NULL arrays"))); } dx = (int4 *) ARR_DATA_PTR(idx); dim = ARRNELEMS(idx); size = offsetof(NDBOX, x[0]) + sizeof(double) * 2 * dim; result = (NDBOX *) palloc(size); memset(result, 0, size); result->size = size; result->dim = dim; for (i = 0; i < dim; i++) { if ((dx[i] <= 0) || (dx[i] > c->dim)) { pfree(result); ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("Index out of bounds"))); } result->x[i] = c->x[dx[i] - 1]; result->x[i + dim] = c->x[dx[i] + c->dim - 1]; } PG_FREE_IF_COPY(c,0); PG_RETURN_NDBOX(result); }
Datum citext_hash_extended(PG_FUNCTION_ARGS) { text *txt = PG_GETARG_TEXT_PP(0); uint64 seed = PG_GETARG_INT64(1); char *str; Datum result; str = str_tolower(VARDATA_ANY(txt), VARSIZE_ANY_EXHDR(txt), DEFAULT_COLLATION_OID); result = hash_any_extended((unsigned char *) str, strlen(str), seed); pfree(str); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(txt, 0); PG_RETURN_DATUM(result); }
Datum cube_out(PG_FUNCTION_ARGS) { NDBOX *cube = PG_GETARG_NDBOX(0); StringInfoData buf; int dim = DIM(cube); int i; int ndig; initStringInfo(&buf); /* * Get the number of digits to display. */ ndig = DBL_DIG + extra_float_digits; if (ndig < 1) ndig = 1; /* * while printing the first (LL) corner, check if it is equal to the * second one */ appendStringInfoChar(&buf, '('); for (i = 0; i < dim; i++) { if (i > 0) appendStringInfoString(&buf, ", "); appendStringInfo(&buf, "%.*g", ndig, LL_COORD(cube, i)); } appendStringInfoChar(&buf, ')'); if (!cube_is_point_internal(cube)) { appendStringInfoString(&buf, ",("); for (i = 0; i < dim; i++) { if (i > 0) appendStringInfoString(&buf, ", "); appendStringInfo(&buf, "%.*g", ndig, UR_COORD(cube, i)); } appendStringInfoChar(&buf, ')'); } PG_FREE_IF_COPY(cube, 0); PG_RETURN_CSTRING(buf.data); }
Datum gin_extract_hstore(PG_FUNCTION_ARGS) { HStore *hs = PG_GETARG_HS(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); Datum *entries = NULL; *nentries = 2 * hs->size; if (hs->size > 0) { HEntry *ptr = ARRPTR(hs); char *words = STRPTR(hs); int i = 0; entries = (Datum *) palloc(sizeof(Datum) * 2 * hs->size); while (ptr - ARRPTR(hs) < hs->size) { text *item; item = makeitem(words + ptr->pos, ptr->keylen); *VARDATA(item) = KEYFLAG; entries[i++] = PointerGetDatum(item); if (ptr->valisnull) { item = makeitem(NULL, 0); *VARDATA(item) = NULLFLAG; } else { item = makeitem(words + ptr->pos + ptr->keylen, ptr->vallen); *VARDATA(item) = VALFLAG; } entries[i++] = PointerGetDatum(item); ptr++; } } PG_FREE_IF_COPY(hs, 0); PG_RETURN_POINTER(entries); }
Datum sfcgal_area3D(PG_FUNCTION_ARGS) { GSERIALIZED *input; sfcgal_geometry_t *geom; double result; sfcgal_postgis_init(); input = PG_GETARG_GSERIALIZED_P(0); geom = POSTGIS2SFCGALGeometry(input); result = sfcgal_geometry_area_3d(geom); sfcgal_geometry_delete(geom); PG_FREE_IF_COPY(input, 0); PG_RETURN_FLOAT8(result); }
Datum pg_gen_salt(PG_FUNCTION_ARGS) { text *arg0 = PG_GETARG_TEXT_PP(0); int len; char buf[PX_MAX_SALT_LEN + 1]; text_to_cstring_buffer(arg0, buf, sizeof(buf)); len = px_gen_salt(buf, buf, 0); if (len < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("gen_salt: %s", px_strerror(len)))); PG_FREE_IF_COPY(arg0, 0); PG_RETURN_TEXT_P(cstring_to_text_with_len(buf, len)); }
Datum text2ltree(PG_FUNCTION_ARGS) { text *in = PG_GETARG_TEXT_P(0); char *s = (char *) palloc(VARSIZE(in) - VARHDRSZ + 1); ltree *out; memcpy(s, VARDATA(in), VARSIZE(in) - VARHDRSZ); s[VARSIZE(in) - VARHDRSZ] = '\0'; out = (ltree *) DatumGetPointer(DirectFunctionCall1( ltree_in, PointerGetDatum(s) )); pfree(s); PG_FREE_IF_COPY(in, 0); PG_RETURN_POINTER(out); }
Datum sfcgal_volume(PG_FUNCTION_ARGS) { GSERIALIZED *input; sfcgal_geometry_t *geom; double result; sfcgal_postgis_init(); input = (GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); geom = POSTGIS2SFCGALGeometry(input); result = sfcgal_geometry_volume(geom); sfcgal_geometry_delete(geom); PG_FREE_IF_COPY(input, 0); PG_RETURN_FLOAT8(result); }
Datum sfcgal_orientation(PG_FUNCTION_ARGS) { GSERIALIZED *input; sfcgal_geometry_t *geom; int result; sfcgal_postgis_init(); input = PG_GETARG_GSERIALIZED_P(0); geom = POSTGIS2SFCGALGeometry(input); result = sfcgal_geometry_orientation(geom); sfcgal_geometry_delete(geom); PG_FREE_IF_COPY(input, 0); PG_RETURN_INT32(result); }
/* * bpchar needs a specialized hash function because we want to ignore * trailing blanks in comparisons. * * XXX is there any need for locale-specific behavior here? */ Datum hashbpchar(PG_FUNCTION_ARGS) { BpChar *key = PG_GETARG_BPCHAR_P(0); char *keydata; int keylen; Datum result; keydata = VARDATA(key); keylen = bcTruelen(key); result = hash_any((unsigned char *) keydata, keylen); /* Avoid leaking memory for toasted inputs */ PG_FREE_IF_COPY(key, 0); return result; }
Datum sfcgal_make_solid(PG_FUNCTION_ARGS) { GSERIALIZED *output; GSERIALIZED *input = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom = lwgeom_from_gserialized(input); PG_FREE_IF_COPY(input, 0); if (! lwgeom) { lwerror("sfcgal_make_solid: Unable to deserialize input"); } FLAGS_SET_SOLID( lwgeom->flags, 1); output = geometry_serialize( lwgeom ); lwgeom_free(lwgeom); PG_RETURN_POINTER(output); }
Datum LWGEOM_numpoints_linestring(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); int count = -1; if ( lwgeom->type == LINETYPE ) count = lwgeom_count_vertices(lwgeom); lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); /* OGC says this functions is only valid on LINESTRING */ if ( count < 0 ) PG_RETURN_NULL(); PG_RETURN_INT32(count); }
Datum LWGEOM_dimension(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); int dimension = -1; dimension = lwgeom_dimension(lwgeom); lwgeom_free(lwgeom); PG_FREE_IF_COPY(geom, 0); if ( dimension < 0 ) { elog(NOTICE, "Could not compute geometry dimensions"); PG_RETURN_NULL(); } PG_RETURN_INT32(dimension); }
/* * debug function, used only for view query * which will be executed in non-leaf pages in index */ Datum tsquerytree(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); INFIX nrm; text *res; ITEM *q; int4 len; if (query->size == 0) { res = (text *) palloc(VARHDRSZ); VARATT_SIZEP(res) = VARHDRSZ; PG_RETURN_POINTER(res); } q = clean_NOT_v2(GETQUERY(query), &len); if (!q) { res = (text *) palloc(1 + VARHDRSZ); VARATT_SIZEP(res) = 1 + VARHDRSZ; *((char *) VARDATA(res)) = 'T'; } else { nrm.curpol = q; nrm.buflen = 32; nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); *(nrm.cur) = '\0'; nrm.op = GETOPERAND(query); infix(&nrm, true); res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ); VARATT_SIZEP(res) = nrm.cur - nrm.buf + VARHDRSZ; strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf); pfree(q); } PG_FREE_IF_COPY(query, 0); PG_RETURN_POINTER(res); }
Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *result; int type = gserialized_get_type(geom); int32 idx; LWCOLLECTION *coll; LWGEOM *subgeom; POSTGIS_DEBUG(2, "LWGEOM_geometryn_collection called."); /* elog(NOTICE, "GeometryN called"); */ idx = PG_GETARG_INT32(1); idx -= 1; /* index is 1-based */ /* call is valid on multi* geoms only */ if (type==POINTTYPE || type==LINETYPE || type==CIRCSTRINGTYPE || type==COMPOUNDTYPE || type==POLYGONTYPE || type==CURVEPOLYTYPE || type==TRIANGLETYPE) { if ( idx == 0 ) PG_RETURN_POINTER(geom); PG_RETURN_NULL(); } coll = lwgeom_as_lwcollection(lwgeom_from_gserialized(geom)); if ( idx < 0 ) PG_RETURN_NULL(); if ( idx >= coll->ngeoms ) PG_RETURN_NULL(); subgeom = coll->geoms[idx]; subgeom->srid = coll->srid; /* COMPUTE_BBOX==TAINTING */ if ( coll->bbox ) lwgeom_add_bbox(subgeom); result = geometry_serialize(subgeom); lwcollection_free(coll); PG_FREE_IF_COPY(geom, 0); PG_RETURN_POINTER(result); }
Datum ts_match_tq(PG_FUNCTION_ARGS) { TSVector vector; TSQuery query = PG_GETARG_TSQUERY(1); bool res; vector = DatumGetTSVector(DirectFunctionCall1(to_tsvector, PG_GETARG_DATUM(0))); res = DatumGetBool(DirectFunctionCall2(ts_match_vq, TSVectorGetDatum(vector), TSQueryGetDatum(query))); pfree(vector); PG_FREE_IF_COPY(query, 1); PG_RETURN_BOOL(res); }