Datum geography_from_geometry(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(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 */ if ( lwgeom->srid != SRID_DEFAULT ) { ereport(ERROR, ( errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Only SRID %d is currently supported in geography.", SRID_DEFAULT))); } /* Check if the geography has valid coordinate range. */ if ( lwgeom_check_geodetic(lwgeom) == LW_FALSE ) { ereport(ERROR, ( errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Coordinate values are out of range [-180 -90, 180 90] for GEOGRAPHY type" ))); } /* ** 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); }
static Datum gin_btree_extract_value(FunctionCallInfo fcinfo, bool is_varlena) { Datum datum = PG_GETARG_DATUM(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); Datum *entries = (Datum *) palloc(sizeof(Datum)); if (is_varlena) datum = PointerGetDatum(PG_DETOAST_DATUM(datum)); entries[0] = datum; *nentries = 1; PG_RETURN_POINTER(entries); }
Datum pcpoint_out(PG_FUNCTION_ARGS) { PCPOINT *pcpt = NULL; PCSCHEMA *schema = NULL; SERIALIZED_POINT *serpt = NULL; char *hexwkb = NULL; serpt = (SERIALIZED_POINT*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); schema = pc_schema_from_pcid(serpt->pcid, fcinfo); pcpt = pc_point_deserialize(serpt, schema); hexwkb = pc_point_to_hexwkb(pcpt); pc_point_free(pcpt); PG_RETURN_CSTRING(hexwkb); }
Datum pcpatch_out(PG_FUNCTION_ARGS) { PCPATCH *patch = NULL; SERIALIZED_PATCH *serpatch = NULL; char *hexwkb = NULL; PCSCHEMA *schema = NULL; serpatch = (SERIALIZED_PATCH*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); schema = pc_schema_from_pcid(serpatch->pcid, fcinfo); patch = pc_patch_deserialize(serpatch, schema); hexwkb = pc_patch_to_hexwkb(patch); pc_patch_free(patch); PG_RETURN_CSTRING(hexwkb); }
Datum rank_cd_def(PG_FUNCTION_ARGS) { tsvector *txt = (tsvector *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)); float4 res; res = calc_rank_cd(weights, txt, query, (PG_NARGS() == 3) ? PG_GETARG_DATUM(2) : DEF_NORM_METHOD); PG_FREE_IF_COPY(txt, 0); PG_FREE_IF_COPY(query, 1); PG_RETURN_FLOAT4(res); }
/* * ExecIndexEvalRuntimeKeys * Evaluate any runtime key values, and update the scankeys. */ void ExecIndexEvalRuntimeKeys( expr_ctx_n *econtext, index_runtime_key_info_s *runtimeKeys, int numRuntimeKeys) { int j; struct mctx* oldContext; /* We want to keep the key values in per-tuple memory */ oldContext = mctx_switch(econtext->ecxt_per_tuple_memory); for (j = 0; j < numRuntimeKeys; j++) { struct scankey* scan_key = runtimeKeys[j].scan_key; expr_state_n* key_expr = runtimeKeys[j].key_expr; datum_t scanvalue; bool isNull; /* * For each run-time key, extract the run-time expression and evaluate * it with respect to the current context. We then stick the result * into the proper scan key. * * Note: the result of the eval could be a pass-by-ref value that's * stored in some outer scan's tuple, not in * econtext->ecxt_per_tuple_memory. We assume that the outer tuple * will stay put throughout our scan. If this is wrong, we could copy * the result into our context explicitly, but I think that's not * necessary. * * It's also entirely possible that the result of the eval is a * toasted value. In this case we should forcibly detoast it, to * avoid repeat detoastings each time the value is examined by an * index support function. */ scanvalue = EXEC_EVAL_EXPR(key_expr, econtext, &isNull, NULL); if (isNull) { scan_key->sk_argument = scanvalue; scan_key->sk_flags |= SK_ISNULL; } else { if (runtimeKeys[j].key_toastable) scanvalue = PTR_TO_D(PG_DETOAST_DATUM(scanvalue)); scan_key->sk_argument = scanvalue; scan_key->sk_flags &= ~SK_ISNULL; } } mctx_switch(oldContext); }
/** * Peak into a #GSERIALIZED datum to find the bounding box. If the * box is there, copy it out and return it. If not, calculate the box from the * full object and return the box based on that. If no box is available, * return #LW_FAILURE, otherwise #LW_SUCCESS. */ static int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df) { GSERIALIZED *gpart; uint8_t flags; int result = LW_SUCCESS; POSTGIS_DEBUG(4, "entered function"); /* ** The most info we need is the 8 bytes of serialized header plus the ** of floats necessary to hold the bounding box. */ gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 8 + sizeof(BOX2DF)); flags = gpart->flags; POSTGIS_DEBUGF(4, "got flags %d", gpart->flags); /* Do we even have a serialized bounding box? */ if ( FLAGS_GET_BBOX(flags) ) { /* Yes! Copy it out into the box! */ POSTGIS_DEBUG(4, "copying box out of serialization"); memcpy(box2df, gpart->data, sizeof(BOX2DF)); result = LW_SUCCESS; } else { /* No, we need to calculate it from the full object. */ GBOX gbox; GSERIALIZED *g = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); LWGEOM *lwgeom = lwgeom_from_gserialized(g); if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE ) { POSTGIS_DEBUG(4, "could not calculate bbox, returning failure"); lwgeom_free(lwgeom); return LW_FAILURE; } lwgeom_free(lwgeom); result = box2df_from_gbox_p(&gbox, box2df); } if ( result == LW_SUCCESS ) { POSTGIS_DEBUGF(4, "got box2df %s", box2df_to_string(box2df)); } return result; }
Datum gin_extract_tsquery(PG_FUNCTION_ARGS) { QUERYTYPE *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); uint32 *nentries = (uint32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = DatumGetUInt16(PG_GETARG_DATUM(2)); Datum *entries = NULL; *nentries = 0; if (query->size > 0) { int4 i, j = 0, len; ITEM *item; item = clean_NOT_v2(GETQUERY(query), &len); if (!item) elog(ERROR, "Query requires full scan, GIN doesn't support it"); item = GETQUERY(query); for (i = 0; i < query->size; i++) if (item[i].type == VAL) (*nentries)++; entries = (Datum *) palloc(sizeof(Datum) * (*nentries)); for (i = 0; i < query->size; i++) if (item[i].type == VAL) { text *txt; txt = (text *) palloc(VARHDRSZ + item[i].length); VARATT_SIZEP(txt) = VARHDRSZ + item[i].length; memcpy(VARDATA(txt), GETOPERAND(query) + item[i].distance, item[i].length); entries[j++] = PointerGetDatum(txt); if (strategy == 1 && item[i].weight != 0) elog(ERROR, "With class of lexeme restrictions use @@@ operation"); } } PG_FREE_IF_COPY(query, 0); PG_RETURN_POINTER(entries); }
Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS) { GSERIALIZED *geom = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); GBOX gbox; BOX3D *result; int rv = lwgeom_calculate_gbox(lwgeom, &gbox); if ( rv == LW_FAILURE ) PG_RETURN_NULL(); result = box3d_from_gbox(&gbox); PG_RETURN_POINTER(result); }
Datum gbt_var_fetch(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GBT_VARKEY *key = (GBT_VARKEY *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)); GBT_VARKEY_R r = gbt_var_key_readable(key); GISTENTRY *retval; retval = palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(r.lower), entry->rel, entry->page, entry->offset, TRUE); PG_RETURN_POINTER(retval); }
Datum geography_from_binary(PG_FUNCTION_ARGS) { char *wkb_bytea = (char*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *gser = NULL; size_t wkb_size = VARSIZE(wkb_bytea); uint8_t *wkb = (uint8_t*)VARDATA(wkb_bytea); LWGEOM *lwgeom = lwgeom_from_wkb(wkb, wkb_size, LW_PARSER_CHECK_NONE); if ( ! lwgeom ) lwerror("Unable to parse WKB"); gser = gserialized_geography_from_lwgeom(lwgeom, 0); lwgeom_free(lwgeom); PG_RETURN_POINTER(gser); }
Datum ts_rankcd_wtt(PG_FUNCTION_ARGS) { ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); TSVector txt = PG_GETARG_TSVECTOR(1); TSQuery query = PG_GETARG_TSQUERY(2); float res; res = calc_rank_cd(getWeights(win), txt, query, DEF_NORM_METHOD); PG_FREE_IF_COPY(win, 0); PG_FREE_IF_COPY(txt, 1); PG_FREE_IF_COPY(query, 2); PG_RETURN_FLOAT4(res); }
Datum lwgeom_eq(PG_FUNCTION_ARGS) { GSERIALIZED *geom1 = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *geom2 = (GSERIALIZED *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); GBOX box1; GBOX box2; bool result; POSTGIS_DEBUG(2, "lwgeom_eq called"); if (gserialized_get_srid(geom1) != gserialized_get_srid(geom2)) { elog(BTREE_SRID_MISMATCH_SEVERITY, "Operation on two GEOMETRIES with different SRIDs\n"); PG_FREE_IF_COPY(geom1, 0); PG_FREE_IF_COPY(geom2, 1); PG_RETURN_NULL(); } gserialized_get_gbox_p(geom1, &box1); gserialized_get_gbox_p(geom2, &box2); PG_FREE_IF_COPY(geom1, 0); PG_FREE_IF_COPY(geom2, 1); if ( ! (FPeq(box1.xmin, box2.xmin) && FPeq(box1.ymin, box2.ymin) && FPeq(box1.xmax, box2.xmax) && FPeq(box1.ymax, box2.ymax)) ) { result = FALSE; } else { result = TRUE; } PG_RETURN_BOOL(result); }
Datum LWGEOM_line_locate_point(PG_FUNCTION_ARGS) { GSERIALIZED *geom1 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *geom2 = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); LWLINE *lwline; LWPOINT *lwpoint; POINTARRAY *pa; POINT2D p; double ret; if ( gserialized_get_type(geom1) != LINETYPE ) { elog(ERROR,"line_locate_point: 1st arg isnt a line"); PG_RETURN_NULL(); } if ( gserialized_get_type(geom2) != POINTTYPE ) { elog(ERROR,"line_locate_point: 2st arg isnt a point"); PG_RETURN_NULL(); } if ( gserialized_get_srid(geom1) != gserialized_get_srid(geom2) ) { elog(ERROR, "Operation on two geometries with different SRIDs"); PG_RETURN_NULL(); } lwline = lwgeom_as_lwline(lwgeom_from_gserialized(geom1)); lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2)); pa = lwline->points; lwpoint_getPoint2d_p(lwpoint, &p); ret = ptarray_locate_point(pa, &p, NULL); PG_RETURN_FLOAT8(ret); }
Datum subarray(PG_FUNCTION_ARGS) { ArrayType *a = (ArrayType *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); ArrayType *result; int32 start = (PG_GETARG_INT32(1) > 0) ? PG_GETARG_INT32(1) - 1 : PG_GETARG_INT32(1); int32 len = (fcinfo->nargs == 3) ? PG_GETARG_INT32(2) : 0; int32 end = 0; int32 c; CHECKARRVALID(a); if (ARRISVOID(a)) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } c = ARRNELEMS(a); if (start < 0) start = c + start; if (len < 0) end = c + len; else if (len == 0) end = c; else end = start + len; if (end > c) end = c; if (start < 0) start = 0; if (start >= end || end <= 0) { PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(new_intArrayType(0)); } result = new_intArrayType(end - start); if (end - start > 0) memcpy(ARRPTR(result), ARRPTR(a) + start, (end - start) * sizeof(int32)); PG_FREE_IF_COPY(a, 0); PG_RETURN_POINTER(result); }
char * SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) { char *result; Datum origval, val; bool isnull; Oid typoid, foutoid; bool typisvarlena; SPI_result = 0; if (fnumber > tupdesc->natts || fnumber == 0 || fnumber <= FirstLowInvalidHeapAttributeNumber) { SPI_result = SPI_ERROR_NOATTRIBUTE; return NULL; } origval = heap_getattr(tuple, fnumber, tupdesc, &isnull); if (isnull) return NULL; if (fnumber > 0) typoid = tupdesc->attrs[fnumber - 1]->atttypid; else typoid = (SystemAttributeDefinition(fnumber, true))->atttypid; getTypeOutputInfo(typoid, &foutoid, &typisvarlena); /* * If we have a toasted datum, forcibly detoast it here to avoid memory * leakage inside the type's output routine. */ if (typisvarlena) val = PointerGetDatum(PG_DETOAST_DATUM(origval)); else val = origval; result = OidOutputFunctionCall(foutoid, val); /* Clean up detoasted copy, if any */ if (val != origval) pfree(DatumGetPointer(val)); return result; }
Datum ts_rank_wttf(PG_FUNCTION_ARGS) { ArrayType *win = (ArrayType *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); TSVector txt = PG_GETARG_TSVECTOR(1); TSQuery query = PG_GETARG_TSQUERY(2); int method = PG_GETARG_INT32(3); float res; res = calc_rank(getWeights(win), txt, query, method); PG_FREE_IF_COPY(win, 0); PG_FREE_IF_COPY(txt, 1); PG_FREE_IF_COPY(query, 2); PG_RETURN_FLOAT4(res); }
Datum LWGEOM_numpoints_linestring(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int32 ret; POSTGIS_DEBUG(2, "LWGEOM_numpoints_linestring called."); ret = lwgeom_numpoints_linestring_recursive(SERIALIZED_FORM(geom)); if ( ret == -1 ) { PG_FREE_IF_COPY(geom, 0); PG_RETURN_NULL(); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_INT32(ret); }
Datum g_cube_decompress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); NDBOX *key = DatumGetNDBOX(PG_DETOAST_DATUM(entry->key)); if (key != DatumGetNDBOX(entry->key)) { GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(key), entry->rel, entry->page, entry->offset, FALSE); PG_RETURN_POINTER(retval); } PG_RETURN_POINTER(entry); }
/* * For BTGreaterEqualStrategyNumber, BTGreaterStrategyNumber, and * BTEqualStrategyNumber we want to start the index scan at the * supplied query datum, and work forward. For BTLessStrategyNumber * and BTLessEqualStrategyNumber, we need to start at the leftmost * key, and work forward until the supplied query datum (which must be * sent along inside the QueryInfo structure). */ static Datum gin_btree_extract_query(FunctionCallInfo fcinfo, bool is_varlena, Datum (*leftmostvalue) (void), Datum (*typecmp) (FunctionCallInfo)) { Datum datum = PG_GETARG_DATUM(0); int32 *nentries = (int32 *) PG_GETARG_POINTER(1); StrategyNumber strategy = PG_GETARG_UINT16(2); bool **partialmatch = (bool **) PG_GETARG_POINTER(3); Pointer **extra_data = (Pointer **) PG_GETARG_POINTER(4); Datum *entries = (Datum *) palloc(sizeof(Datum)); QueryInfo *data = (QueryInfo *) palloc(sizeof(QueryInfo)); bool *ptr_partialmatch; *nentries = 1; ptr_partialmatch = *partialmatch = (bool *) palloc(sizeof(bool)); *ptr_partialmatch = false; if (is_varlena) datum = PointerGetDatum(PG_DETOAST_DATUM(datum)); data->strategy = strategy; data->datum = datum; data->is_varlena = is_varlena; data->typecmp = typecmp; *extra_data = (Pointer *) palloc(sizeof(Pointer)); **extra_data = (Pointer) data; switch (strategy) { case BTLessStrategyNumber: case BTLessEqualStrategyNumber: entries[0] = leftmostvalue(); *ptr_partialmatch = true; break; case BTGreaterEqualStrategyNumber: case BTGreaterStrategyNumber: *ptr_partialmatch = true; case BTEqualStrategyNumber: entries[0] = datum; break; default: elog(ERROR, "unrecognized strategy number: %d", strategy); } PG_RETURN_POINTER(entries); }
Datum ltree_decompress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); ltree_gist *key = (ltree_gist *) DatumGetPointer(PG_DETOAST_DATUM(entry->key)); if (PointerGetDatum(key) != entry->key) { GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(key), entry->rel, entry->page, entry->offset, FALSE); PG_RETURN_POINTER(retval); } PG_RETURN_POINTER(entry); }
Datum LWGEOM_dimension(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int dimension; POSTGIS_DEBUG(2, "LWGEOM_dimension called"); dimension = lwgeom_dimension_recursive(SERIALIZED_FORM(geom)); if ( dimension == -1 ) { PG_FREE_IF_COPY(geom, 0); elog(ERROR, "Something went wrong in dimension computation"); PG_RETURN_NULL(); } PG_FREE_IF_COPY(geom, 0); PG_RETURN_INT32(dimension); }
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); }
/* * DatumGetAnyArrayP: return either an expanded array or a detoasted varlena * array. The result must not be modified in-place. */ AnyArrayType * DatumGetAnyArrayP(Datum d) { ExpandedArrayHeader *eah; /* * If it's an expanded array (RW or RO), return the header pointer. */ if (VARATT_IS_EXTERNAL_EXPANDED(DatumGetPointer(d))) { eah = (ExpandedArrayHeader *) DatumGetEOHP(d); Assert(eah->ea_magic == EA_MAGIC); return (AnyArrayType *) eah; } /* Else do regular detoasting as needed */ return (AnyArrayType *) PG_DETOAST_DATUM(d); }
Datum gmol_decompress(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); bytea *key = (bytea*)DatumGetPointer(PG_DETOAST_DATUM(entry->key)); if (key != (bytea *) DatumGetPointer(entry->key)) { GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY)); gistentryinit(*retval, PointerGetDatum(key), entry->rel, entry->page, entry->offset, false); PG_RETURN_POINTER(retval); } PG_RETURN_POINTER(entry); }
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 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); }
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); }
/* * 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); }
static void print_value(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, int i) { bool typisvarlena; bool isnull; Oid typoutput; Form_pg_attribute attr = tupdesc->attrs[i]; Datum origval = fastgetattr(tuple, i + 1, tupdesc, &isnull); Oid typid = attr->atttypid; getTypeOutputInfo(typid, &typoutput, &typisvarlena); if (isnull) { appendStringInfoString(s, "null"); } else if (typisvarlena && VARATT_IS_EXTERNAL_ONDISK(origval)) { appendStringInfoString(s, "\"???unchanged-toast-datum???\""); } else if (!typisvarlena) { print_literal(s, typid, OidOutputFunctionCall(typoutput, origval)); } else { Datum val = PointerGetDatum(PG_DETOAST_DATUM(origval)); print_literal(s, typid, OidOutputFunctionCall(typoutput, val)); } }