From: Bborie Park Date: Sun, 13 Apr 2014 03:07:41 +0000 (+0000) Subject: Addition of GUC postgis.gdal_enabled_drivers with default set to all GDAL drivers... X-Git-Tag: 2.2.0rc1~1130 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=55e3d2dbb3fb30f0a6af3174430acb8a8e10c662;p=postgis Addition of GUC postgis.gdal_enabled_drivers with default set to all GDAL drivers disabled git-svn-id: http://svn.osgeo.org/postgis/trunk@12474 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/NEWS b/NEWS index 394c10c3d..323939e82 100644 --- a/NEWS +++ b/NEWS @@ -6,8 +6,8 @@ PostGIS 2.2.0 - #2565, ST_SummaryStats(tablename, rastercolumn, ...) uses ST_SummaryStatsAgg() - #2567, ST_Count(tablename, rastercolumn, ...) uses ST_CountAgg() - - By default, PostGIS raster prevents usage of GDAL VRT, WCS, WMS, - PDF and MEM drivers + - By default, PostGIS raster disables all GDAL drivers affecting + out-db rasters, ST_FromGDALRaster() and ST_AsGDALRaster() variants * Deprecated signatures * @@ -17,7 +17,9 @@ PostGIS 2.2.0 * New Features * - Added missing variants of ST_TPI(), ST_TRI() and ST_Roughness() - - #1678, Added GUC postgis.gdal.datapath to specify GDAL config + - Added GUC postgis.gdal_enabled_drivers to specify GDAL config + variable GDAL_SKIP + - #1678, Added GUC postgis.gdal_datapath to specify GDAL config variable GDAL_DATA - #2341, New mask parameter for ST_MapAlgebra - #2397, read encoding info automatically in shapefile loader diff --git a/raster/rt_core/librtcore.h b/raster/rt_core/librtcore.h index 2cf4054fb..2d0cd298d 100644 --- a/raster/rt_core/librtcore.h +++ b/raster/rt_core/librtcore.h @@ -2126,8 +2126,8 @@ rt_util_gdal_configured(void); /* register all GDAL drivers */ -void -rt_util_gdal_register_all(void); +int +rt_util_gdal_register_all(int force_register_all); /* is the driver registered? diff --git a/raster/rt_core/rt_band.c b/raster/rt_core/rt_band.c index ce088d22b..a2fd81c2d 100644 --- a/raster/rt_core/rt_band.c +++ b/raster/rt_core/rt_band.c @@ -359,7 +359,7 @@ rt_band_load_offline_data(rt_band band) { #endif - rt_util_gdal_register_all(); + rt_util_gdal_register_all(0); /* hdsSrc = GDALOpenShared(band->data.offline.path, GA_ReadOnly); */ diff --git a/raster/rt_core/rt_raster.c b/raster/rt_core/rt_raster.c index 53c8d46f0..371a4c2e4 100644 --- a/raster/rt_core/rt_raster.c +++ b/raster/rt_core/rt_raster.c @@ -1619,7 +1619,7 @@ rt_raster_to_gdal( assert(NULL != gdalsize); /* any supported format is possible */ - rt_util_gdal_register_all(); + rt_util_gdal_register_all(0); RASTER_DEBUG(3, "loaded all supported GDAL formats"); /* output format not specified */ @@ -1715,7 +1715,7 @@ rt_raster_gdal_drivers(uint32_t *drv_count, uint8_t cancc) { assert(drv_count != NULL); - rt_util_gdal_register_all(); + rt_util_gdal_register_all(0); count = GDALGetDriverCount(); RASTER_DEBUGF(3, "%d drivers found", count); diff --git a/raster/rt_core/rt_util.c b/raster/rt_core/rt_util.c index 5fe875781..6960c6e17 100644 --- a/raster/rt_core/rt_util.c +++ b/raster/rt_core/rt_util.c @@ -331,18 +331,20 @@ int rt_util_gdal_configured(void) { /* register all GDAL drivers */ -void -rt_util_gdal_register_all(void) { +int +rt_util_gdal_register_all(int force_register_all) { static int registered = 0; - if (registered) { + if (registered && !force_register_all) { RASTER_DEBUG(3, "Already called once... not calling GDALAllRegister"); - return; + return 0; } RASTER_DEBUG(3, "Calling GDALAllRegister"); GDALAllRegister(); registered = 1; + + return 1; } /* diff --git a/raster/rt_pg/rtpg_create.c b/raster/rt_pg/rtpg_create.c index bea9cc17f..1dd5f5a6b 100644 --- a/raster/rt_pg/rtpg_create.c +++ b/raster/rt_pg/rtpg_create.c @@ -725,7 +725,7 @@ Datum RASTER_addBandOutDB(PG_FUNCTION_ARGS) } /* open outdb raster file */ - rt_util_gdal_register_all(); + rt_util_gdal_register_all(0); hdsOut = GDALOpenShared(outdbfile, GA_ReadOnly); if (hdsOut == NULL) { if (pgraster != NULL) { diff --git a/raster/rt_pg/rtpg_gdal.c b/raster/rt_pg/rtpg_gdal.c index 468ce2ea5..e787bafd7 100644 --- a/raster/rt_pg/rtpg_gdal.c +++ b/raster/rt_pg/rtpg_gdal.c @@ -94,7 +94,7 @@ Datum RASTER_fromGDALRaster(PG_FUNCTION_ARGS) } /* register all GDAL drivers */ - rt_util_gdal_register_all(); + rt_util_gdal_register_all(0); /* open GDAL raster */ hdsSrc = GDALOpenShared("/vsimem/in.dat", GA_ReadOnly); diff --git a/raster/rt_pg/rtpostgis.c b/raster/rt_pg/rtpostgis.c index a9a5b32b7..0c750e702 100644 --- a/raster/rt_pg/rtpostgis.c +++ b/raster/rt_pg/rtpostgis.c @@ -138,6 +138,7 @@ #include "lwgeom_pg.h" #include "rtpostgis.h" +#include "rtpg_internal.h" /* * This is required for builds against pgsql @@ -152,7 +153,6 @@ void _PG_init(void); /* ---------------------------------------------------------------- */ static char *gdaldatapath = NULL; -static char *gdaldisableddrivers = NULL; static char *gdalenableddrivers = NULL; /* postgis.gdal_datapath */ @@ -172,52 +172,130 @@ rtpg_assignHookGDALDataPath(const char *newpath, void *extra) { POSTGIS_RT_DEBUGF(4, "GDAL_DATA = %s", CPLGetConfigOption("GDAL_DATA", NULL)); } -/* postgis.gdal_disabled_drivers */ +/* postgis.gdal_enabled_drivers */ +#define ENABLE_ALL "ENABLE_ALL" +#define DISABLE_ALL "DISABLE_ALL" static void -rtpg_assignHookGDALDisabledDrivers(const char *newdrivers, void *extra) { - POSTGIS_RT_DEBUGF(4, "GDAL_SKIP = %s", CPLGetConfigOption("GDAL_SKIP", NULL)); - POSTGIS_RT_DEBUGF(4, "disableddrivers = %s", newdrivers); - POSTGIS_RT_DEBUGF(4, "gdaldisableddrivers = %s", gdaldisableddrivers); - POSTGIS_RT_DEBUGF(4, "gdalenableddrivers = %s", gdalenableddrivers); +rtpg_assignHookGDALEnabledDrivers(const char *enabled_drivers, void *extra) { + int enable_all = 0; + int disable_all = 0; - /* enabled drivers always take presidence */ - if (gdalenableddrivers != NULL) - return; + char **enabled_drivers_array = NULL; + int enabled_drivers_count = 0; + char *gdal_skip = NULL; - /* set GDAL_SKIP */ - CPLSetConfigOption("GDAL_SKIP", newdrivers); - POSTGIS_RT_DEBUGF(4, "GDAL_SKIP = %s", CPLGetConfigOption("GDAL_SKIP", NULL)); -} + uint32_t i; + uint32_t j; -/* postgis.gdal_enabled_drivers */ -static void -rtpg_assignHookGDALEnabledDrivers(const char *newdrivers, void *extra) { POSTGIS_RT_DEBUGF(4, "GDAL_SKIP = %s", CPLGetConfigOption("GDAL_SKIP", NULL)); - POSTGIS_RT_DEBUGF(4, "enableddrivers = %s", newdrivers); - POSTGIS_RT_DEBUGF(4, "gdaldisableddrivers = %s", gdaldisableddrivers); - POSTGIS_RT_DEBUGF(4, "gdalenableddrivers = %s", gdalenableddrivers); + POSTGIS_RT_DEBUGF(4, "enabled_drivers = %s", enabled_drivers); - /* all other drivers than those in this list are added to GDAL_SKIP */ + /* if NULL, nothing to do */ + if (enabled_drivers == NULL) + return; + + /* destroy the driver manager */ + /* this is the only way to ensure GDAL_SKIP is recognized */ + GDALDestroyDriverManager(); + CPLSetConfigOption("GDAL_SKIP", NULL); + + /* force wrapper function to call GDALAllRegister() */ + rt_util_gdal_register_all(1); + + enabled_drivers_array = rtpg_strsplit(enabled_drivers, " ", &enabled_drivers_count); + + /* scan for keywords DISABLE_ALL and ENABLE_ALL */ + disable_all = 0; + enable_all = 0; + if (strstr(enabled_drivers, DISABLE_ALL) != NULL) { + for (i = 0; i < enabled_drivers_count; i++) { + if (strstr(enabled_drivers_array[i], DISABLE_ALL) != NULL) { + disable_all = 1; + break; + } + } + } + else if (strstr(enabled_drivers, ENABLE_ALL) != NULL) { + for (i = 0; i < enabled_drivers_count; i++) { + if (strstr(enabled_drivers_array[i], ENABLE_ALL) != NULL) { + enable_all = 1; + break; + } + } + } + + if (!enable_all) { + int found = 0; + uint32_t drv_count = 0; + rt_gdaldriver drv_set = rt_raster_gdal_drivers(&drv_count, 0); + POSTGIS_RT_DEBUGF(4, "driver count = %d", drv_count); + + /* all other drivers than those in new drivers are added to GDAL_SKIP */ + for (i = 0; i < drv_count; i++) { + found = 0; + + if (!disable_all) { + /* gdal driver found in enabled_drivers, continue to thorough search */ + if (strstr(enabled_drivers, drv_set[i].short_name) != NULL) { + /* thorough search of enabled_drivers */ + for (j = 0; j < enabled_drivers_count; j++) { + /* driver found */ + if (strcmp(enabled_drivers_array[j], drv_set[i].short_name) == 0) { + found = 1; + break; + } + } + } + } + + /* driver found, continue */ + if (found) + continue; + + /* driver not found, add to gdal_skip */ + if (gdal_skip == NULL) { + gdal_skip = palloc(sizeof(char) * (strlen(drv_set[i].short_name) + 1)); + sprintf(gdal_skip, "%s", drv_set[i].short_name); + } + else { + gdal_skip = repalloc( + gdal_skip, + sizeof(char) * ( + strlen(gdal_skip) + 1 + strlen(drv_set[i].short_name) + 1 + ) + ); + sprintf(gdal_skip, "%s %s", gdal_skip, drv_set[i].short_name); + } + } + + for (i = 0; i < drv_count; i++) { + pfree(drv_set[i].short_name); + pfree(drv_set[i].long_name); + pfree(drv_set[i].create_options); + } + if (drv_count) pfree(drv_set); + + } + + /* destroy the driver manager */ + /* this is the only way to ensure GDAL_SKIP is recognized */ + GDALDestroyDriverManager(); /* set GDAL_SKIP */ - /* - CPLSetConfigOption("GDAL_SKIP", newdrivers); - */ + POSTGIS_RT_DEBUGF(4, "gdal_skip = %s", gdal_skip); + CPLSetConfigOption("GDAL_SKIP", gdal_skip); + if (gdal_skip != NULL) pfree(gdal_skip); + + /* force wrapper function to call GDALAllRegister() */ + rt_util_gdal_register_all(1); + + pfree(enabled_drivers_array); + POSTGIS_RT_DEBUGF(4, "GDAL_SKIP = %s", CPLGetConfigOption("GDAL_SKIP", NULL)); } /* Module load callback */ void _PG_init(void) { - const char *gdal_skip; - - /* - * restrict GDAL drivers - * unless already set, default to: - * VRT, WMS, WCS, PDF, MEM, HTTP, RPFTOC, PCIDSK - */ - gdal_skip = CPLGetConfigOption("GDAL_SKIP", NULL); - if (gdal_skip == NULL) - CPLSetConfigOption("GDAL_SKIP", "VRT WMS WCS MEM PDF HTTP RPFTOC PCIDSK"); /* Install liblwgeom handlers */ pg_install_lwgeom_handlers(); @@ -241,29 +319,24 @@ _PG_init(void) { NULL /* GucShowHook show_hook */ ); - DefineCustomStringVariable( - "postgis.gdal_disabled_drivers", /* name */ - "Enabled GDAL drivers.", /* short_desc */ - "List of disabled GDAL drivers. (sets the GDAL_SKIP config option).", /* long_desc */ - &gdaldisableddrivers, /* valueAddr */ - NULL, /* bootValue */ - PGC_SUSET, /* GucContext context */ - 0, /* int flags */ -#if POSTGIS_PGSQL_VERSION >= 91 - NULL, /* GucStringCheckHook check_hook */ -#endif - rtpg_assignHookGDALDisabledDrivers, /* GucStringAssignHook assign_hook */ - NULL /* GucShowHook show_hook */ - ); - + /* + * GucContext is set to PGC_BACKEND. As per PostgreSQL's guc.h... + * + * BACKEND options can only be set at postmaster startup, from the + * configuration file, or by client request in the connection startup + * packet (e.g., from libpq's PGOPTIONS variable). Furthermore, an + * already-started backend will ignore changes to such an option in the + * configuration file. The idea is that these options are fixed for a + * given backend once it's started, but they can vary across backends. + */ DefineCustomStringVariable( "postgis.gdal_enabled_drivers", /* name */ "Enabled GDAL drivers.", /* short_desc */ - "List of enabled GDAL drivers. If both postgis.gdal_enabled_drivers and postgis.disabled_drivers is set, postgis.gdal_disabled_drivers is ignored. (sets the GDAL_SKIP config option).", /* long_desc */ + "List of enabled GDAL drivers by short name. To enable/disable all drivers, use 'ENABLE_ALL' or 'DISABLE_ALL' (sets the GDAL_SKIP config option).", /* long_desc */ &gdalenableddrivers, /* valueAddr */ - NULL, /* bootValue */ + DISABLE_ALL, /* bootValue */ PGC_SUSET, /* GucContext context */ - 0, /* int flags */ + GUC_LIST_INPUT, /* int flags */ #if POSTGIS_PGSQL_VERSION >= 91 NULL, /* GucStringCheckHook check_hook */ #endif diff --git a/raster/test/regress/check_gdal.sql b/raster/test/regress/check_gdal.sql index 0e9ab3d94..f15368e6a 100644 --- a/raster/test/regress/check_gdal.sql +++ b/raster/test/regress/check_gdal.sql @@ -1,3 +1,4 @@ +-- postgis.gdal_datapath SELECT CASE WHEN strpos(postgis_gdal_version(), 'GDAL_DATA') <> 0 @@ -18,3 +19,25 @@ SELECT THEN false ELSE NULL END; + +-- postgis.gdal_enabled_drivers +SET client_min_messages TO warning; + +SELECT count(*) = 0 FROM ST_GDALDrivers(); +SHOW postgis.gdal_enabled_drivers; + +SET postgis.gdal_enabled_drivers = 'ENABLE_ALL'; +SHOW postgis.gdal_enabled_drivers; +SELECT count(*) > 0 FROM ST_GDALDrivers(); + +SET postgis.gdal_enabled_drivers = 'GTiff PNG JPEG'; +SHOW postgis.gdal_enabled_drivers; +SELECT count(*) = 3 FROM ST_GDALDrivers(); + +SET postgis.gdal_enabled_drivers = 'DISABLE_ALL'; +SHOW postgis.gdal_enabled_drivers; +SELECT count(*) = 0 FROM ST_GDALDrivers(); + +SET postgis.gdal_enabled_drivers = default; +SHOW postgis.gdal_enabled_drivers; +SELECT count(*) = 0 FROM ST_GDALDrivers(); diff --git a/raster/test/regress/check_gdal_expected b/raster/test/regress/check_gdal_expected index e69de29bb..4a96f73af 100644 --- a/raster/test/regress/check_gdal_expected +++ b/raster/test/regress/check_gdal_expected @@ -0,0 +1,10 @@ +t +DISABLE_ALL +ENABLE_ALL +t +GTiff PNG JPEG +t +DISABLE_ALL +t +DISABLE_ALL +t diff --git a/raster/test/regress/load_outdb-pre.pl b/raster/test/regress/load_outdb-pre.pl index 530c3fb0b..a2faff90c 100755 --- a/raster/test/regress/load_outdb-pre.pl +++ b/raster/test/regress/load_outdb-pre.pl @@ -13,6 +13,7 @@ if (lc($^O) eq "msys") { } my $sql = <<"END"; +SET postgis.gdal_enabled_drivers = 'GTiff'; DROP TABLE IF EXISTS raster_outdb_template; CREATE TABLE raster_outdb_template AS SELECT diff --git a/raster/test/regress/load_outdb-pre.sh b/raster/test/regress/load_outdb-pre.sh index b085761ed..41dbd05e1 100755 --- a/raster/test/regress/load_outdb-pre.sh +++ b/raster/test/regress/load_outdb-pre.sh @@ -11,6 +11,7 @@ if [ "$CSYS" == "msys" ]; then fi SQL=" \ +SET postgis.gdal_enabled_drivers = 'GTiff'; DROP TABLE IF EXISTS raster_outdb_template; \ CREATE TABLE raster_outdb_template AS \ SELECT \ diff --git a/raster/test/regress/loader/BasicOutDB.select.sql b/raster/test/regress/loader/BasicOutDB.select.sql index 9148b6ced..7ac68f147 100644 --- a/raster/test/regress/loader/BasicOutDB.select.sql +++ b/raster/test/regress/loader/BasicOutDB.select.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'GTiff'; DELETE FROM loadedrast WHERE filename != 'testraster.tif'; SELECT srid, scale_x::numeric(16, 10), scale_y::numeric(16, 10), blocksize_x, blocksize_y, same_alignment, regular_blocking, num_bands, pixel_types, nodata_values::numeric(16,10)[], out_db, ST_AsEWKT(extent) FROM raster_columns WHERE r_table_name = 'loadedrast' AND r_raster_column = 'rast'; SELECT ST_AsEWKT(geom), val FROM (SELECT (ST_PixelAsPolygons(rast, 1)).* FROM loadedrast WHERE rid = 1) foo WHERE x = 1 AND y = 1; diff --git a/raster/test/regress/permitted_gdal_drivers.sql b/raster/test/regress/permitted_gdal_drivers.sql index ddd3d6f71..4e2ff5f76 100644 --- a/raster/test/regress/permitted_gdal_drivers.sql +++ b/raster/test/regress/permitted_gdal_drivers.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'GTiff PNG JPEG'; INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +datum=WGS84 +no_defs '); INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (3857,'EPSG',3857,'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3857"],AXIS["X",EAST],AXIS["Y",NORTH]]','+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs'); diff --git a/raster/test/regress/rt_asgdalraster.sql b/raster/test/regress/rt_asgdalraster.sql index 5f8c99a47..eca026cdf 100644 --- a/raster/test/regress/rt_asgdalraster.sql +++ b/raster/test/regress/rt_asgdalraster.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'GTiff PNG JPEG'; SELECT CASE WHEN length( ST_AsGDALRaster( diff --git a/raster/test/regress/rt_asjpeg.sql b/raster/test/regress/rt_asjpeg.sql index 12ffd5b72..6f7e0e70c 100644 --- a/raster/test/regress/rt_asjpeg.sql +++ b/raster/test/regress/rt_asjpeg.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'JPEG'; SELECT ST_AsJPEG(NULL) IS NULL; SELECT CASE WHEN length( diff --git a/raster/test/regress/rt_aspng.sql b/raster/test/regress/rt_aspng.sql index 60e6f7138..501f0af2e 100644 --- a/raster/test/regress/rt_aspng.sql +++ b/raster/test/regress/rt_aspng.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'PNG'; SELECT ST_AsPNG(NULL) IS NULL; SELECT CASE WHEN length( diff --git a/raster/test/regress/rt_astiff.sql b/raster/test/regress/rt_astiff.sql index f59fccf1c..1342a4acf 100644 --- a/raster/test/regress/rt_astiff.sql +++ b/raster/test/regress/rt_astiff.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'GTiff'; SELECT ST_AsTIFF(NULL) IS NULL; SELECT ST_AsTIFF(NULL, 'JPEG') IS NULL; SELECT CASE diff --git a/raster/test/regress/rt_bytea.sql b/raster/test/regress/rt_bytea.sql index 16e298aa5..ae4bd5ebe 100644 --- a/raster/test/regress/rt_bytea.sql +++ b/raster/test/regress/rt_bytea.sql @@ -182,6 +182,7 @@ DROP TABLE rt_bytea_test; ----------------------------------------------------------------------- --- Test out-db as in-db ----------------------------------------------------------------------- +SET postgis.gdal_enabled_drivers = 'GTiff'; WITH foo AS ( SELECT rid, diff --git a/raster/test/regress/rt_fromgdalraster.sql b/raster/test/regress/rt_fromgdalraster.sql index 96b049d33..c80ff6151 100644 --- a/raster/test/regress/rt_fromgdalraster.sql +++ b/raster/test/regress/rt_fromgdalraster.sql @@ -1,3 +1,4 @@ +SET postgis.gdal_enabled_drivers = 'GTiff PNG'; /* Driver: PNG/Portable Network Graphics Files: testraster.png