Commit 07ca520a authored by Raúl Marín's avatar Raúl Marín

Cache getSRIDbySRS

Closes #4672
Closes https://github.com/postgis/postgis/pull/557
parent d427c87f
Pipeline #141798895 passed with stage
in 26 minutes and 44 seconds
......@@ -13,6 +13,7 @@ Only tickets not included in 3.1.0alpha1
- #4651: ST_Simplify: Don't copy if nothing is removed (Raúl Marín)
- #4657: Avoid De-TOASTing where possible (Paul Ramsey)
- #4490, Tweak function costs (Raúl Marín)
- #4672, Cache getSRSbySRID and getSRIDbySRS (Raúl Marín)
* Bug fixes *
- #4652, Fix several memory related bugs in ST_GeomFromGML (Raúl Marín)
......
......@@ -11,6 +11,8 @@
**********************************************************************/
#include "postgres.h"
#include "catalog/pg_type.h" /* for CSTRINGOID */
#include "executor/spi.h"
#include "fmgr.h"
#include "utils/memutils.h"
......@@ -438,4 +440,108 @@ GetSRSCacheBySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
arg->srs = getSRSbySRID(fcinfo, srid, short_crs);
}
return arg->srs;
}
/*
* Retrieve an SRID from a given SRS
* Require valid spatial_ref_sys table entry
*
*/
static int32_t
getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
{
static const int16_t max_query_size = 512;
char query[512];
Oid argtypes[] = {CSTRINGOID};
Datum values[] = {CStringGetDatum(srs)};
int32_t srid, err;
postgis_initialize_cache(fcinfo);
snprintf(query,
max_query_size,
"SELECT srid "
"FROM %s, "
"regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
"WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
postgis_spatial_ref_sys());
if (!srs)
return 0;
if (SPI_OK_CONNECT != SPI_connect())
{
elog(NOTICE, "getSRIDbySRS: could not connect to SPI manager");
return 0;
}
err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
if (err < 0)
{
elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
SPI_finish();
return 0;
}
/* no entry in spatial_ref_sys */
if (SPI_processed <= 0)
{
snprintf(query,
max_query_size,
"SELECT srid "
"FROM %s, "
"regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
"WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
postgis_spatial_ref_sys());
err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
if (err < 0)
{
elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
SPI_finish();
return 0;
}
if (SPI_processed <= 0)
{
SPI_finish();
return 0;
}
}
srid = atoi(SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1));
SPI_finish();
return srid;
}
static inline SRIDCache *
SRIDCacheGet(FunctionCallInfo fcinfo)
{
const uint32_t entry_number = SRID_CACHE_ENTRY;
GenericCacheCollection *generic_cache = GetGenericCacheCollection(fcinfo);
SRIDCache *cache = (SRIDCache *)(generic_cache->entry[entry_number]);
if (!cache)
{
cache = MemoryContextAllocZero(PostgisCacheContext(fcinfo), sizeof(SRIDCache));
cache->type = entry_number;
generic_cache->entry[entry_number] = (GenericCache *)cache;
}
return cache;
}
int32_t
GetSRIDCacheBySRS(FunctionCallInfo fcinfo, const char *srs)
{
SRIDCache *cache = SRIDCacheGet(fcinfo);
SRIDCacheArgument *arg = &(cache->arg[0]);
if (!arg->srid || strcmp(srs, arg->srs) != 0)
{
size_t size = strlen(srs) + 1;
arg->srid = getSRIDbySRS(fcinfo, srs);
arg->srs = MemoryContextAlloc(PostgisCacheContext(fcinfo), size);
memcpy(arg->srs, srs, size);
}
return arg->srid;
}
\ No newline at end of file
......@@ -28,6 +28,7 @@
#define RECT_CACHE_ENTRY 4
#define TOAST_CACHE_ENTRY 5
#define SRSDESC_CACHE_ENTRY 6
#define SRID_CACHE_ENTRY 7
#define NUM_CACHE_ENTRIES 8
......@@ -149,4 +150,19 @@ typedef struct {
const char *GetSRSCacheBySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs);
/******************************************************************************/
#define SRIDCacheSize 1
typedef struct {
char *srs;
int32_t srid;
} SRIDCacheArgument;
typedef struct {
int type;
SRIDCacheArgument arg[SRIDCacheSize];
} SRIDCache;
int32_t GetSRIDCacheBySRS(FunctionCallInfo fcinfo, const char *srs);
#endif /* LWGEOM_CACHE_H_ */
......@@ -42,7 +42,6 @@
#include "lwgeom_cache.h"
#include "lwgeom_pg.h" /* For debugging macros. */
#include "geography.h" /* For utility functions. */
#include "lwgeom_export.h" /* For export functions. */
#include "lwgeom_transform.h"
Datum geography_in(PG_FUNCTION_ARGS);
......
......@@ -41,7 +41,6 @@
#include "liblwgeom.h" /* For standard geometry types. */
#include "lwgeom_pg.h" /* For debugging macros. */
#include "geography.h" /* For utility functions. */
#include "lwgeom_export.h" /* For export functions. */
#include "lwgeom_transform.h" /* for srid_is_latlon */
......
......@@ -31,7 +31,6 @@
#include "float.h" /* for DBL_DIG */
#include "postgres.h"
#include "catalog/pg_type.h" /* for CSTRINGOID */
#include "executor/spi.h"
#include "utils/builtins.h"
#include "utils/jsonb.h"
......@@ -40,7 +39,6 @@
#include "lwgeom_cache.h"
#include "lwgeom_pg.h"
#include "liblwgeom.h"
#include "lwgeom_export.h"
Datum LWGEOM_asGML(PG_FUNCTION_ARGS);
Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS);
......@@ -51,78 +49,6 @@ Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS);
Datum geometry_to_json(PG_FUNCTION_ARGS);
Datum geometry_to_jsonb(PG_FUNCTION_ARGS);
/*
* Retrieve an SRID from a given SRS
* Require valid spatial_ref_sys table entry
*
*/
int
getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
{
static const int16_t max_query_size = 512;
char query[512];
Oid argtypes[] = {CSTRINGOID};
Datum values[] = {CStringGetDatum(srs)};
int32_t srid, err;
postgis_initialize_cache(fcinfo);
snprintf(query,
max_query_size,
"SELECT srid "
"FROM %s, "
"regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
"WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
postgis_spatial_ref_sys());
if (!srs) return 0;
if (SPI_OK_CONNECT != SPI_connect())
{
elog(NOTICE, "getSRIDbySRS: could not connect to SPI manager");
return 0;
}
err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
if (err < 0)
{
elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
SPI_finish();
return 0;
}
/* no entry in spatial_ref_sys */
if (SPI_processed <= 0)
{
snprintf(query,
max_query_size,
"SELECT srid "
"FROM %s, "
"regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
"WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
postgis_spatial_ref_sys());
err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
if (err < 0)
{
elog(NOTICE, "getSRIDbySRS: error executing query %d", err);
SPI_finish();
return 0;
}
if (SPI_processed <= 0)
{
SPI_finish();
return 0;
}
}
srid = atoi(SPI_getvalue(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1));
SPI_finish();
return srid;
}
/**
* Encode feature in GML
*/
......
/**********************************************************************
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.net
*
* PostGIS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* PostGIS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
*
**********************************************************************
*
* Copyright 2009 Olivier Courtin <[email protected]>
*
**********************************************************************/
int getSRIDbySRS(FunctionCallInfo fcinfo, const char *SRS);
......@@ -42,7 +42,6 @@ static void geohash_lwpgerror(char *msg, __attribute__((__unused__)) int error_c
lwpgerror("%s", msg);
}
#include "lwgeom_export.h"
static GBOX*
parse_geohash(char *geohash, int precision)
......
......@@ -30,7 +30,7 @@
#include "../postgis_config.h"
#include "lwgeom_pg.h"
#include "liblwgeom.h"
#include "lwgeom_export.h"
#include "lwgeom_cache.h"
#if defined(HAVE_LIBJSON)
......@@ -110,7 +110,7 @@ Datum geom_from_geojson(PG_FUNCTION_ARGS)
if (srs)
{
srid = getSRIDbySRS(fcinfo, srs);
srid = GetSRIDCacheBySRS(fcinfo, srs);
lwfree(srs);
}
......
......@@ -45,7 +45,7 @@
#include "funcapi.h"
#include "liblwgeom.h"
#include "lwgeom_export.h"
#include "lwgeom_cache.h"
#include "lwgeom_pg.h"
#include "geography.h" /* for lwgeom_valid_typmod */
#include "lwgeom_transform.h"
......@@ -147,7 +147,7 @@ Datum LWGEOM_in(PG_FUNCTION_ARGS)
lwgeom = lwgeom_from_geojson(str, &srs);
if (srs)
{
srid = getSRIDbySRS(fcinfo, srs);
srid = GetSRIDCacheBySRS(fcinfo, srs);
lwfree(srs);
lwgeom_set_srid(lwgeom, srid);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment