Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package pgsql-ogr-fdw for openSUSE:Factory checked in at 2021-05-17 18:45:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/pgsql-ogr-fdw (Old) and /work/SRC/openSUSE:Factory/.pgsql-ogr-fdw.new.2988 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "pgsql-ogr-fdw" Mon May 17 18:45:33 2021 rev:2 rq:893786 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/pgsql-ogr-fdw/pgsql-ogr-fdw.changes 2020-07-05 01:19:10.869186719 +0200 +++ /work/SRC/openSUSE:Factory/.pgsql-ogr-fdw.new.2988/pgsql-ogr-fdw.changes 2021-05-17 18:46:03.560434051 +0200 @@ -1,0 +2,17 @@ +Mon May 17 13:25:27 UTC 2021 - Bruno Friedmann <br...@ioda-net.ch> + +- Update to version 1.1.0 + + New options for handling multi-sheet worksheets + + Better handling of character encoding for sources with non-UTF8 data + + Functions to display version info and list available drivers +- Packaging + + fix build for pg13 + + Use llvmjit for all Leap and pg11+ + + rename %pgversion macro to %pg_flavor + +------------------------------------------------------------------- +Mon May 17 11:11:39 UTC 2021 - Dominique Leuenberger <dims...@opensuse.org> + +- Fix build with RPM 4.16: bare words are no longer supported. + +------------------------------------------------------------------- Old: ---- pgsql-ogr-fdw-1.0.12.tar.gz New: ---- pgsql-ogr-fdw-1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ pgsql-ogr-fdw.spec ++++++ --- /var/tmp/diff_new_pack.mjiMCB/_old 2021-05-17 18:46:04.020432099 +0200 +++ /var/tmp/diff_new_pack.mjiMCB/_new 2021-05-17 18:46:04.024432082 +0200 @@ -1,7 +1,7 @@ # -# spec file for package pgsql-ogr-fdw +# spec file # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,50 +16,52 @@ # -%define pgversion @BUILD_FLAVOR@ +%define pg_flavor @BUILD_FLAVOR@ %define sname pgsql-ogr-fdw %define pg_bindir %(pg_config --bindir) %define pg_libdir %(pg_config --pkglibdir) %define pg_share %(pg_config --sharedir) -%if 0%{?is_opensuse} && ("%{pgversion}" == "postgresql11" || "%{pgversion}" == "postgresql12") && 0%{?suse_version} >= 1550 +%if 0%{?is_opensuse} && ("%{pg_flavor}" == "postgresql11" || "%{pg_flavor}" == "postgresql12" || "%{pg_flavor}" == "postgresql13") %bcond_without llvm %else %bcond_with llvm %endif -Version: 1.0.12 +Version: 1.1.0 Release: 0 Summary: PostgreSQL OGR Foreign Data Wrapper License: MIT Group: Productivity/Databases/Tools URL: https://github.com/pramsey/pgsql-ogr-fdw Source0: https://codeload.github.com/pramsey/pgsql-ogr-fdw/tar.gz/v%{version}#/%{sname}-%{version}.tar.gz -BuildRequires: %{pgversion}-server -%if "%{pgversion}" == "postgresql11" || "%{pgversion}" == "postgresql12" -BuildRequires: %{pgversion}-server-devel -%endif -BuildRequires: %{pgversion}-devel +BuildRequires: %{pg_flavor}-devel BuildRequires: gcc-c++ BuildRequires: gdal-devel BuildRequires: pkgconfig -%requires_eq %{pgversion}-server -%requires_eq %{pgversion}-server-llvmjit -%if "%{pgversion}" == "" || "%{pgversion}" == "postgresql" +%requires_eq %{pg_flavor}-server +BuildRequires: %{pg_flavor}-server +%if "%{pg_flavor}" == "postgresql11" || "%{pg_flavor}" == "postgresql12" || "%{pg_flavor}" == "postgresql13" +BuildRequires: %{pg_flavor}-server-devel +%if %{with llvm} +BuildRequires: %{pg_flavor}-llvmjit +%endif +%endif +%if "%{pg_flavor}" == "" || "%{pg_flavor}" == "postgresql" Name: %{sname} ExclusiveArch: do_not_build %else -Name: %{pgversion}-%{sname} +Name: %{pg_flavor}-%{sname} %endif # Build for pg11&12 but not for Leap 15.1 (due to lack of maintenance) -%if (0%{?is_opensuse} && 0%{?sle_version} == 150100) && ("%{pgversion}" == "postgresql11" || "%{pgversion}" == "postgresql12") +%if (0%{?is_opensuse} && 0%{?sle_version} == 150100) && ("%{pg_flavor}" == "postgresql11" || "%{pg_flavor}" == "postgresql12") ExclusiveArch: do_not_build %endif -%if 0%{?suse_version} < 1315 && %{pgversion} == "postgresql10" +%if 0%{?suse_version} < 1315 && "%{pg_flavor}" == "postgresql10" ExclusiveArch: do_not_build %endif -%if 0%{?suse_version} == 1500 && %{pgversion} == "postgresql95" +%if 0%{?suse_version} == 1500 && "%{pg_flavor}" == "postgresql95" ExclusiveArch: do_not_build %endif -%if "%{pgversion}" == "" +%if "%{pg_flavor}" == "" Name: %{sname} ExclusiveArch: do_not_build %endif @@ -73,10 +75,10 @@ %package llvmjit Summary: Just-in-time compilation support for PostgreSQL %{sname} extension Group: Productivity/Databases/Tools -Requires: %{pgversion}-%{sname} = %{version}-%{release} -Requires: %{pgversion}-llvmjit -Requires: %{pgversion}-server -Supplements: (%{pgversion}-llvmjit and %{name}) +Requires: %{pg_flavor}-%{sname} = %{version}-%{release} +Requires: %{pg_flavor}-llvmjit +Requires: %{pg_flavor}-server +Supplements: (%{pg_flavor}-llvmjit and %{name}) %description llvmjit This package contains support for just-in-time compiling parts of @@ -102,10 +104,10 @@ make V=1 USE_PGXS=1 install DESTDIR=%{buildroot} %post -%{_datadir}/postgresql/install-alternatives %pgversion +%{_datadir}/postgresql/install-alternatives %pg_flavor %postun -%{_datadir}/postgresql/install-alternatives %pgversion +%{_datadir}/postgresql/install-alternatives %pg_flavor %files %defattr(-, root, root) @@ -114,7 +116,8 @@ %{pg_bindir}/ogr_fdw_info %{pg_libdir}/ogr_fdw.so %dir %{pg_share}/extension/ -%{pg_share}/extension/ogr_fdw--1.0.sql +%{pg_share}/extension/ogr_fdw--1.0--1.1.sql +%{pg_share}/extension/ogr_fdw--1.1.sql %{pg_share}/extension/ogr_fdw.control %if %{with llvm} ++++++ pgsql-ogr-fdw-1.0.12.tar.gz -> pgsql-ogr-fdw-1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/META.json new/pgsql-ogr-fdw-1.1.0/META.json --- old/pgsql-ogr-fdw-1.0.12/META.json 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/META.json 2021-02-01 18:55:33.000000000 +0100 @@ -2,7 +2,7 @@ "name": "ogr_fdw", "abstract": "OGR foreign data wrapper", "description": "OGR FDW allows you to connect to any OGR supported data source.", - "version": "1.0.9", + "version": "1.1.0", "maintainer": [ "Paul Ramsey <pram...@cleverelephant.ca>" ], @@ -21,9 +21,9 @@ }, "provides": { "ogr_fdw": { - "file": "ogr_fdw--1.0.sql", + "file": "ogr_fdw--1.1.sql", "docfile": "README.md", - "version": "1.0.9", + "version": "1.1.0", "abstract": "OGR FDW wrapper" } }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/Makefile new/pgsql-ogr-fdw-1.1.0/Makefile --- old/pgsql-ogr-fdw-1.0.12/Makefile 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/Makefile 2021-02-01 18:55:33.000000000 +0100 @@ -1,9 +1,18 @@ # ogr_fdw/Makefile MODULE_big = ogr_fdw -OBJS = ogr_fdw.o ogr_fdw_deparse.o ogr_fdw_common.o stringbuffer_pg.o + +OBJS = \ + ogr_fdw.o \ + ogr_fdw_deparse.o \ + ogr_fdw_common.o \ + ogr_fdw_func.o \ + stringbuffer_pg.o + EXTENSION = ogr_fdw -DATA = ogr_fdw--1.0.sql +DATA = \ + ogr_fdw--1.0--1.1.sql \ + ogr_fdw--1.1.sql REGRESS = ogr_fdw diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/README.md new/pgsql-ogr-fdw-1.1.0/README.md --- old/pgsql-ogr-fdw-1.0.12/README.md 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/README.md 2021-02-01 18:55:33.000000000 +0100 @@ -11,7 +11,7 @@ This implementation currently has the following limitations: * **PostgreSQL 9.3 or higher.** This wrapper does not support the FDW implementations in older versions of PostgreSQL. -* **Limited non-spatial query restrictions are pushed down to OGR.** OGR only supports a minimal set of SQL operators (>, <, <=, >=, =). +* **Limited non-spatial query restrictions are pushed down to OGR.** OGR only supports a [minimal set](https://gdal.org/user/ogr_sql_dialect.html) of SQL operators (>, <, <=, >=, =). * **Only bounding box filters (&&) are pushed down.** Spatial filtering is possible, but only bounding boxes, and only using the && operator. * **OGR connections every time** Rather than pooling OGR connections, each query makes (and disposes of) **two** new ones, which seems to be the largest performance drag at the moment for restricted (small) queries. * **All columns are retrieved every time.** PostgreSQL foreign data wrappers don't require all columns all the time, and some efficiencies can be gained by only requesting the columns needed to fulfill a query. This would be a minimal efficiency improvement, but can be removed given some development time, since the OGR API supports returning a subset of columns. @@ -58,20 +58,20 @@ # ogr_fdw_info -s /tmp/test -l pt_two -CREATE SERVER myserver +CREATE SERVER "myserver" FOREIGN DATA WRAPPER ogr_fdw OPTIONS ( datasource '/tmp/test', format 'ESRI Shapefile' ); -CREATE FOREIGN TABLE pt_two ( +CREATE FOREIGN TABLE "pt_two" ( fid integer, - geom geometry(Point, 4326), - name varchar, - age integer, - height real, - birthdate date ) - SERVER myserver + "geom" geometry(Point, 4326), + "name" varchar, + "age" integer, + "height" real, + "birthdate" date ) + SERVER "myserver" OPTIONS (layer 'pt_two'); ``` @@ -200,6 +200,8 @@ ### PostgreSQL FDW Wraparound action! Handy for testing. Connect your database back to your database and watch the fur fly. +This is only for testing, for best performance you should use postgres_fdw foreign data wrapper even when querying a PostGIS enabled database. + ```sql CREATE TABLE apostles ( fid serial primary key, @@ -424,3 +426,38 @@ ); ``` +### Utility Functions + +To view the current FDW and GDAL version. + +```sql +SELECT ogr_fdw_version(); +``` + +To view the drivers supported by this GDAL. + +```sql +SELECT unnest(ogr_fdw_drivers()); +``` + + +### Character Encoding + +To access sources that have a non-UTF-8 encoding, you may need to specify the character encoding in your server creation line. OGR FDW uses the transcoding built into PostgreSQL, and thus supports all the [encodings that PostgreSQL does](https://www.postgresql.org/docs/current/multibyte.html#CHARSET-TABLE). + +```sql +CREATE SERVER odbc_latin1 + FOREIGN DATA WRAPPER ogr_fdw + OPTIONS ( + datasource 'ODBC:username@servicename', + format 'ODBC', + character_encoding 'WIN1250' + ); + +CREATE FOREIGN TABLE featuretable_fdw ( + name text, + geom geometry(Point, 4326) +) +SERVER odbc_latin1 + OPTIONS (layer 'featuretable'); +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/input/file.source new/pgsql-ogr-fdw-1.1.0/input/file.source --- old/pgsql-ogr-fdw-1.0.12/input/file.source 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/input/file.source 2021-02-01 18:55:33.000000000 +0100 @@ -91,10 +91,29 @@ OPTIONS ( layer 'enc' ); SET client_min_messages = debug1; -SELECT * FROM e_1 WHERE fid = 1; +SELECT fid, name FROM e_1 WHERE fid = 1; SET client_min_messages = notice; ------------------------------------------------ +-- Using encoding option directly + +CREATE SERVER myserver_latin1_direct + FOREIGN DATA WRAPPER ogr_fdw + OPTIONS ( + datasource '@abs_srcdir@/data', + format 'ESRI Shapefile', + character_encoding 'LATIN1' + ); + +CREATE FOREIGN TABLE e_2 ( + fid integer, + name varchar ) + SERVER myserver_latin1_direct + OPTIONS ( layer 'enc' ); + +SELECT fid, name FROM e_2 WHERE fid = 1; + +------------------------------------------------ -- Geometryless test CREATE SERVER csvserver @@ -143,7 +162,7 @@ ) SERVER "fgdbserver" OPTIONS (layer 'Cities'); -SET client_min_messages = DEBUG1; +SET client_min_messages = LOG; SELECT fid, city_name, pop1990 FROM cities WHERE pop1990 = 17710; SELECT fid, city_name, pop1990 FROM cities WHERE city_name = 'Williston'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/input/pgsql.source new/pgsql-ogr-fdw-1.1.0/input/pgsql.source --- old/pgsql-ogr-fdw-1.0.12/input/pgsql.source 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/input/pgsql.source 2021-02-01 18:55:33.000000000 +0100 @@ -36,7 +36,7 @@ format 'PostgreSQL' ); CREATE FOREIGN TABLE bytea_fdw ( - fid integer, + fid bigint, geom bytea, name varchar, age bigint, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.0--1.1.sql new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.0--1.1.sql --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.0--1.1.sql 1970-01-01 01:00:00.000000000 +0100 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.0--1.1.sql 2021-02-01 18:55:33.000000000 +0100 @@ -0,0 +1,13 @@ +CREATE OR REPLACE FUNCTION ogr_fdw_version() + RETURNS text + AS 'MODULE_PATHNAME', 'ogr_fdw_version' + LANGUAGE 'c' + IMMUTABLE STRICT + PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION ogr_fdw_drivers() + RETURNS text[] + AS 'MODULE_PATHNAME', 'ogr_fdw_drivers' + LANGUAGE 'c' + IMMUTABLE STRICT + PARALLEL SAFE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.0.sql new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.0.sql --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.0.sql 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.0.sql 1970-01-01 01:00:00.000000000 +0100 @@ -1,18 +0,0 @@ -/* ogr_fdw/ogr_fdw--1.0.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION ogr_fdw" to load this file. \quit - -CREATE FUNCTION ogr_fdw_handler() -RETURNS fdw_handler -AS 'MODULE_PATHNAME' -LANGUAGE 'c' STRICT; - -CREATE FUNCTION ogr_fdw_validator(text[], oid) -RETURNS void -AS 'MODULE_PATHNAME' -LANGUAGE 'c' STRICT; - -CREATE FOREIGN DATA WRAPPER ogr_fdw - HANDLER ogr_fdw_handler - VALIDATOR ogr_fdw_validator; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.1.sql new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.1.sql --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw--1.1.sql 1970-01-01 01:00:00.000000000 +0100 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw--1.1.sql 2021-02-01 18:55:33.000000000 +0100 @@ -0,0 +1,32 @@ +/* ogr_fdw/ogr_fdw--1.1.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION ogr_fdw" to load this file. \quit + +CREATE FUNCTION ogr_fdw_handler() + RETURNS fdw_handler + AS 'MODULE_PATHNAME' + LANGUAGE 'c' STRICT; + +CREATE FUNCTION ogr_fdw_validator(text[], oid) + RETURNS void + AS 'MODULE_PATHNAME' + LANGUAGE 'c' STRICT; + +CREATE FOREIGN DATA WRAPPER ogr_fdw + HANDLER ogr_fdw_handler + VALIDATOR ogr_fdw_validator; + +CREATE OR REPLACE FUNCTION ogr_fdw_version() + RETURNS text + AS 'MODULE_PATHNAME', 'ogr_fdw_version' + LANGUAGE 'c' + IMMUTABLE STRICT + PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION ogr_fdw_drivers() + RETURNS text[] + AS 'MODULE_PATHNAME', 'ogr_fdw_drivers' + LANGUAGE 'c' + IMMUTABLE STRICT + PARALLEL SAFE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw.c new/pgsql-ogr-fdw-1.1.0/ogr_fdw.c --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw.c 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw.c 2021-02-01 18:55:33.000000000 +0100 @@ -56,6 +56,7 @@ #define OPT_CONFIG_OPTIONS "config_options" #define OPT_OPEN_OPTIONS "open_options" #define OPT_UPDATEABLE "updateable" +#define OPT_CHAR_ENCODING "character_encoding" #define OGR_FDW_FRMT_INT64 "%lld" #define OGR_FDW_CAST_INT64(x) (long long)(x) @@ -66,6 +67,8 @@ * ForeignServerRelationId (CREATE SERVER options) * UserMappingRelationId (CREATE USER MAPPING options) * ForeignTableRelationId (CREATE FOREIGN TABLE options) + * + * {optname, optcontext, optrequired, optfound} */ static struct OgrFdwOption valid_options[] = { @@ -78,6 +81,7 @@ {OPT_DRIVER, ForeignServerRelationId, false, false}, {OPT_UPDATEABLE, ForeignServerRelationId, false, false}, {OPT_CONFIG_OPTIONS, ForeignServerRelationId, false, false}, + {OPT_CHAR_ENCODING, ForeignServerRelationId, false, false}, #if GDAL_VERSION_MAJOR >= 2 {OPT_OPEN_OPTIONS, ForeignServerRelationId, false, false}, #endif @@ -542,6 +546,10 @@ { ogr.open_options = defGetString(def); } + if (streq(def->defname, OPT_CHAR_ENCODING)) + { + ogr.char_encoding = pg_char_to_encoding(defGetString(def)); + } if (streq(def->defname, OPT_UPDATEABLE)) { if (defGetBoolean(def)) @@ -644,11 +652,16 @@ : errhint("Does the layer exist?") )); } - ogr.lyr_utf8 = OGR_L_TestCapability(ogr.lyr, OLCStringsAsUTF8); + + if (OGR_L_TestCapability(ogr.lyr, OLCStringsAsUTF8)) + { + ogr.char_encoding = PG_UTF8; + } return ogr; } + /* * Validate the options given to a FOREIGN DATA WRAPPER, SERVER, * USER MAPPING or FOREIGN TABLE that uses ogr_fdw. @@ -666,13 +679,6 @@ const char* config_options = NULL, *open_options = NULL; OgrUpdateable updateable = OGR_UPDATEABLE_FALSE; - /* Check that the database encoding is UTF8, to match OGR internals */ - if (GetDatabaseEncoding() != PG_UTF8) - { - elog(ERROR, "OGR FDW only works with UTF-8 databases"); - PG_RETURN_VOID(); - } - /* Initialize found state to not found */ for (opt = valid_options; opt->optname; opt++) { @@ -1888,9 +1894,9 @@ if (cstr_in && cstr_len > 0) { char* cstr_decoded; - if (execstate->ogr.lyr_utf8) + if (execstate->ogr.char_encoding) { - cstr_decoded = pg_any_to_server(cstr_in, cstr_len, PG_UTF8); + cstr_decoded = pg_any_to_server(cstr_in, cstr_len, execstate->ogr.char_encoding); } else { @@ -1898,6 +1904,9 @@ } nulls[i] = false; values[i] = pgDatumFromCString(cstr_decoded, pgtype, pgtypmod, pginputfunc); + /* Free cstr_decoded if it is a copy */ + if (cstr_in != cstr_decoded) + pfree(cstr_decoded); } else { @@ -3011,9 +3020,10 @@ stringbuffer_init(&buf); err = ogrLayerToSQL(ogr_lyr, - quote_identifier(server->servername), + server->servername, launder_table_names, launder_column_names, + NULL, ogrGetGeometryOid() != BYTEAOID, &buf ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw.control new/pgsql-ogr-fdw-1.1.0/ogr_fdw.control --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw.control 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw.control 2021-02-01 18:55:33.000000000 +0100 @@ -1,5 +1,5 @@ # ogr_fdw extension comment = 'foreign-data wrapper for GIS data access' -default_version = '1.0' +default_version = '1.1' module_pathname = '$libdir/ogr_fdw' relocatable = true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw.h new/pgsql-ogr-fdw-1.1.0/ogr_fdw.h --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw.h 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw.h 2021-02-01 18:55:33.000000000 +0100 @@ -11,6 +11,8 @@ #ifndef _OGR_FDW_H #define _OGR_FDW_H 1 +#define OGR_FDW_RELEASE_NAME "1.1" + /* * PostgreSQL */ @@ -137,7 +139,7 @@ const char* open_options; /* GDAL open options */ OgrUpdateable ds_updateable; OgrUpdateable lyr_updateable; - bool lyr_utf8; /* OGR layer will return UTF8 strings */ + int char_encoding; /* Is OGR layer UTF? Has user provided encoding open option? */ GDALDatasetH ds; /* GDAL datasource handle */ OGRLayerH lyr; /* OGR layer handle */ } OgrConnection; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw_common.c new/pgsql-ogr-fdw-1.1.0/ogr_fdw_common.c --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw_common.c 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw_common.c 2021-02-01 18:55:33.000000000 +0100 @@ -11,6 +11,7 @@ #include "ogr_fdw_gdal.h" #include "ogr_fdw_common.h" #include "stringbuffer.h" +#include "pg_config_manual.h" /* Prototype for function that must be defined in PostgreSQL (it is) */ /* and in ogr_fdw_info (it is) */ @@ -52,8 +53,8 @@ ogrStringLaunder(char *str) { int i, j = 0; - char tmp[STR_MAX_LEN]; - memset(tmp, 0, STR_MAX_LEN); + char tmp[NAMEDATALEN]; + memset(tmp, 0, NAMEDATALEN); for(i = 0; str[i]; i++) { @@ -79,10 +80,10 @@ tmp[j++] = c; /* Avoid mucking with data beyond the end of our stack-allocated strings */ - if ( j >= STR_MAX_LEN ) - j = STR_MAX_LEN - 1; + if ( j >= NAMEDATALEN - 1) + break; } - strncpy(str, tmp, STR_MAX_LEN); + strncpy(str, tmp, NAMEDATALEN); } @@ -220,10 +221,11 @@ static OGRErr ogrColumnNameToSQL (const char *ogrcolname, const char *pgtype, int launder_column_names, stringbuffer_t *buf) { - char pgcolname[STR_MAX_LEN]; - strncpy(pgcolname, ogrcolname, STR_MAX_LEN); + char pgcolname[NAMEDATALEN]; + strncpy(pgcolname, ogrcolname, NAMEDATALEN); ogrStringLaunder(pgcolname); + if ( launder_column_names ) { stringbuffer_aprintf(buf, ",\n %s %s", quote_identifier(pgcolname), pgtype); @@ -250,10 +252,11 @@ OGRErr ogrLayerToSQL (const OGRLayerH ogr_lyr, const char *fdw_server, int launder_table_names, int launder_column_names, + const char *fdw_table_name, int use_postgis_geometry, stringbuffer_t *buf) { int geom_field_count, i; - char table_name[STR_MAX_LEN]; + char table_name[NAMEDATALEN]; OGRFeatureDefnH ogr_fd = OGR_L_GetLayerDefn(ogr_lyr); stringbuffer_t gbuf; @@ -272,9 +275,15 @@ #endif /* Process table name */ - strncpy(table_name, OGR_L_GetName(ogr_lyr), STR_MAX_LEN); - if (launder_table_names) - ogrStringLaunder(table_name); + if (fdw_table_name == NULL) { + strncpy(table_name, OGR_L_GetName(ogr_lyr), NAMEDATALEN); + + if (launder_table_names) + ogrStringLaunder(table_name); + } + else { + strncpy(table_name, fdw_table_name, NAMEDATALEN); + } /* Create table */ stringbuffer_aprintf(buf, "CREATE FOREIGN TABLE %s (\n", quote_identifier(table_name)); @@ -361,9 +370,9 @@ /* Write out attribute fields */ for ( i = 0; i < OGR_FD_GetFieldCount(ogr_fd); i++ ) { - char pgtype[128]; + char pgtype[NAMEDATALEN]; OGRFieldDefnH ogr_fld = OGR_FD_GetFieldDefn(ogr_fd, i); - ogrTypeToPgType(ogr_fld, pgtype, 128); + ogrTypeToPgType(ogr_fld, pgtype, sizeof(pgtype)); ogrColumnNameToSQL(OGR_Fld_GetNameRef(ogr_fld), pgtype, launder_column_names, buf); } @@ -371,7 +380,7 @@ * Add server name and layer-level options. We specify remote * layer name as option */ - stringbuffer_aprintf(buf, "\n) SERVER \"%s\"\nOPTIONS (", quote_identifier(fdw_server)); + stringbuffer_aprintf(buf, "\n) SERVER %s\nOPTIONS (", quote_identifier(fdw_server)); stringbuffer_append(buf, "layer "); ogrDeparseStringLiteral(buf, OGR_L_GetName(ogr_lyr)); stringbuffer_append(buf, ");\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw_common.h new/pgsql-ogr-fdw-1.1.0/ogr_fdw_common.h --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw_common.h 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw_common.h 2021-02-01 18:55:33.000000000 +0100 @@ -27,6 +27,7 @@ OGRErr ogrLayerToSQL (const OGRLayerH ogr_lyr, const char *fwd_server, int launder_table_names, int launder_column_names, + const char *fdw_table_name, int use_postgis_geometry, stringbuffer_t *buf); #endif /* _OGR_FDW_COMMON_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw_deparse.c new/pgsql-ogr-fdw-1.1.0/ogr_fdw_deparse.c --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw_deparse.c 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw_deparse.c 2021-02-01 18:55:33.000000000 +0100 @@ -38,6 +38,13 @@ str->data[len] = '\0'; } +static void +stringInfoReverse(StringInfo str, unsigned int len) +{ + if (str->len > len) + str->len -= len; +} + static char* ogrStringFromDatum(Datum datum, Oid type) { @@ -331,13 +338,13 @@ return NULL != bsearch(&opname, ogrOperators, 10, sizeof(char*), ogrOperatorCmpFunc); } - static bool ogrDeparseOpExprSpatial(OpExpr* node, OgrDeparseCtx* context) { Expr* r_arg = lfirst(list_head(node->args)); Expr* l_arg = lfirst(list_tail(node->args)); - Const* constant; - Var* var; + Expr* exprconst = NULL; + Const* constant = NULL; + Var* var = NULL; OgrFdwColumn col; OGRLayerH lyr; OGRFeatureDefnH fdh; @@ -353,20 +360,23 @@ /* column on the other side that is from the FDW relation */ /* Both of those implies and OGR spatial filter can be reasonably */ /* set. */ - if (nodeTag(r_arg) == T_Const && nodeTag(l_arg) == T_Var) + if (nodeTag(l_arg) == T_Var) { - constant = (Const*)r_arg; var = (Var*)l_arg; + exprconst = r_arg; } - else if (nodeTag(l_arg) == T_Const && nodeTag(r_arg) == T_Var) + else if (nodeTag(r_arg) == T_Var) { - constant = (Const*)l_arg; var = (Var*)r_arg; + exprconst = l_arg; } - else + else return false; + + if (nodeTag(exprconst) == T_Const) { - return false; + constant = (Const*)exprconst; } + else return false; /* Const isn't a geometry type? Done. */ if (constant->consttype != ogrGetGeometryOid() || constant->constisnull || constant->constbyval) @@ -579,9 +589,17 @@ ogrDeparseNullTest(NullTest* node, OgrDeparseCtx* context) { StringInfo buf = context->buf; + /* Only push down simple "col IS NULL" tests */ + if (nodeTag(node->arg) != T_Var) + return false; + + appendStringInfoString(buf, "("); + if(!ogrDeparseVar((Var*)(node->arg), context)) + { + stringInfoReverse(buf, 1); + return false; + } - appendStringInfoChar(buf, '('); - ogrDeparseExpr(node->arg, context); if (node->nulltesttype == IS_NULL) { appendStringInfoString(buf, " IS NULL)"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw_func.c new/pgsql-ogr-fdw-1.1.0/ogr_fdw_func.c --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw_func.c 1970-01-01 01:00:00.000000000 +0100 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw_func.c 2021-02-01 18:55:33.000000000 +0100 @@ -0,0 +1,89 @@ + +/*------------------------------------------------------------------------- + * + * ogr_fdw_func.c + * Helper functions for OGR FDW + * + * Copyright (c) 2020, Paul Ramsey <pram...@cleverelephant.ca> + * + *------------------------------------------------------------------------- + */ + +#include "ogr_fdw.h" +#include "ogr_fdw_gdal.h" + +#include <postgres.h> +#include <fmgr.h> +#include <funcapi.h> +// #include <catalog/pg_type_d.h> +#include <utils/array.h> +#include <utils/builtins.h> + + +/** +*/ +Datum ogr_fdw_drivers(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ogr_fdw_drivers); +Datum ogr_fdw_drivers(PG_FUNCTION_ARGS) +{ + + /* Array building */ + size_t arr_nelems = 0; + Datum *arr_elems; + ArrayType *arr; + Oid elem_type = TEXTOID; + int16 elem_len; + bool elem_byval; + char elem_align; + int num_drivers; + + if (GDALGetDriverCount() <= 0) + GDALAllRegister(); + +#if (GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(1,11,0)) + num_drivers = GDALGetDriverCount(); +#else + num_drivers = OGRGetDriverCount(); +#endif + + if (num_drivers < 1) + PG_RETURN_NULL(); + + arr_elems = palloc0(num_drivers * sizeof(Datum)); + get_typlenbyvalalign(elem_type, &elem_len, &elem_byval, &elem_align); + + int i; + for (i = 0; i < num_drivers; i++) { +#if GDAL_VERSION_MAJOR <= 1 + OGRSFDriverH hDriver = OGRGetDriver(i); + text *txtName = cstring_to_text(OGR_Dr_GetName(hDriver)); + arr_elems[arr_nelems++] = PointerGetDatum(txtName); +#else + GDALDriverH hDriver = GDALGetDriver(i); + if (GDALGetMetadataItem(hDriver, GDAL_DCAP_VECTOR, NULL) != NULL) { + const char *strName = OGR_Dr_GetName(hDriver); + text *txtName = cstring_to_text(strName); + arr_elems[arr_nelems++] = PointerGetDatum(txtName); + } +#endif + } + + arr = construct_array(arr_elems, arr_nelems, elem_type, elem_len, elem_byval, elem_align); + PG_RETURN_ARRAYTYPE_P(arr); +} + +/** +*/ +Datum ogr_fdw_version(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(ogr_fdw_version); +Datum ogr_fdw_version(PG_FUNCTION_ARGS) +{ + const char *gdal_ver = GDAL_RELEASE_NAME; + const char *ogr_fdw_ver = OGR_FDW_RELEASE_NAME; + char ver_str[256]; + snprintf(ver_str, sizeof(ver_str), "OGR_FDW=\"%s\" GDAL=\"%s\"", ogr_fdw_ver, gdal_ver); + text* ver_txt = cstring_to_text(ver_str); + PG_RETURN_TEXT_P(ver_txt); +} + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/ogr_fdw_info.c new/pgsql-ogr-fdw-1.1.0/ogr_fdw_info.c --- old/pgsql-ogr-fdw-1.0.12/ogr_fdw_info.c 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/ogr_fdw_info.c 2021-02-01 18:55:33.000000000 +0100 @@ -9,6 +9,9 @@ *------------------------------------------------------------------------- */ +/* postgresql */ +#include "pg_config_manual.h" + /* getopt */ #include <unistd.h> @@ -20,20 +23,60 @@ static void usage(); static OGRErr ogrListLayers(const char* source); -static OGRErr ogrGenerateSQL(const char* source, const char* layer); +static OGRErr ogrFindLayer(const char* source, int layerno, const char** layer); +static OGRErr ogrGenerateSQL(const char* server, const char* layer, const char* table, const char* source, const char* options); +static int reserved_word(const char* pgcolumn); + +static char * +ogr_fdw_strupr(char* str) +{ + int i; + for (i = 0; i < strlen(str); i++) { + str[i] = toupper(str[i]); + } + + return str; +} -#define STR_MAX_LEN 256 +static char * +strip_spaces(char* str) +{ + unsigned char *cur = (unsigned char *)str; + unsigned char *head = cur; + while (*head != '\0') { + if (*head != ' ') { + *cur = *head; + ++cur; + } + ++head; + } + *cur = '\0'; + return str; +} /* Define this no-op here, so that code */ /* in the ogr_fdw_common module works */ const char* quote_identifier(const char* ident); +char identifier[NAMEDATALEN+3]; + const char* quote_identifier(const char* ident) { - return ident; + int len = (int)MIN(strlen(ident), NAMEDATALEN - 1); + + if (reserved_word(ident)) + { + sprintf(identifier,"\"%*s\"", len, ident); + } + else + { + sprintf(identifier,"%*s", len, ident); + } + return identifier; } +char config_options[STR_MAX_LEN] = {0}; static void @@ -84,10 +127,16 @@ usage() { printf( - "usage: ogr_fdw_info -s <ogr datasource> -l <ogr layer>\n" - " ogr_fdw_info -s <ogr datasource>\n" - " ogr_fdw_info -f\n" - "\n"); + "usage: ogr_fdw_info -s <ogr datasource> -l <ogr layer name> -i <ogr layer index (numeric)> -t <output table name> -n <output server name> -o <config options>\n" + " ogr_fdw_info -s <ogr datasource>\n" + "usage: ogr_fdw_info -f\n" + " Show what input file formats are supported.\n" + "\n"); + printf( + "note (1): You can specify either -l (layer name) or -i (layer index) if you specify both -l will be used\n" + "note (2): config options are specified as a comma deliminated list without the OGR_<driver>_ prefix\n" + "so OGR_XLSX_HEADERS = FORCE OGR_XLSX_FIELD_TYPES = STRING would become:\n\"HEADERS = FORCE,FIELD_TYPES = STRING\"" + "\n"); exit(0); } @@ -95,7 +144,9 @@ main(int argc, char** argv) { int ch; - char* source = NULL, *layer = NULL; + char* source = NULL; + const char* layer = NULL, *server = NULL, *table = NULL, *options = NULL; + int layer_index = -1; OGRErr err = OGRERR_NONE; /* If no options are specified, display usage */ @@ -104,7 +155,7 @@ usage(); } - while ((ch = getopt(argc, argv, "h?s:l:f")) != -1) + while ((ch = getopt(argc, argv, "h?s:l:f:t:n:i:o:")) != -1) { switch (ch) { @@ -117,6 +168,18 @@ case 'f': formats(); break; + case 't': + table = optarg; + break; + case 'n': + server = optarg; + break; + case 'i': + layer_index = atoi(optarg) - 1; + break; + case 'o': + options = optarg; + break; case '?': case 'h': default: @@ -125,13 +188,21 @@ } } - if (source && ! layer) + if (source && ! layer && layer_index == -1) { err = ogrListLayers(source); } - else if (source && layer) + else if (source && (layer || layer_index > -1)) { - err = ogrGenerateSQL(source, layer); + if (! layer) + { + err = ogrFindLayer(source, layer_index, &layer); + } + + if (err == OGRERR_NONE) + { + err = ogrGenerateSQL(server, layer, table, source, options); + } } else if (! source && ! layer) { @@ -140,7 +211,8 @@ if (err != OGRERR_NONE) { - // printf("OGR Error: %s\n\n", CPLGetLastErrorMsg()); + printf("OGR Error: %s\n\n", CPLGetLastErrorMsg()); + exit(1); } OGRCleanupAll(); @@ -168,6 +240,7 @@ CPLError(CE_Failure, CPLE_AppDefined, "Could not connect to source '%s'", source); return OGRERR_FAILURE; } + printf("Format: %s\n\n", GDALGetDriverShortName(GDALGetDatasetDriver(ogr_ds))); printf("Layers:\n"); for (i = 0; i < GDALDatasetGetLayerCount(ogr_ds); i++) @@ -187,15 +260,18 @@ } static OGRErr -ogrGenerateSQL(const char* source, const char* layer) +ogrGenerateSQL(const char* server, const char* layer, const char* table, const char* source, const char* options) { OGRErr err; GDALDatasetH ogr_ds = NULL; GDALDriverH ogr_dr = NULL; OGRLayerH ogr_lyr = NULL; - char server_name[STR_MAX_LEN]; + char server_name[NAMEDATALEN]; stringbuffer_t buf; + char **option_iter; + char **option_list; + GDALAllRegister(); #if GDAL_VERSION_MAJOR < 2 @@ -213,12 +289,49 @@ } if (! ogr_dr) - { ogr_dr = GDALGetDatasetDriver(ogr_ds); + + strcpy(server_name, server == NULL ? "myserver" : server); + + if (options != NULL) { + char *p; + char stripped_config_options[STR_MAX_LEN] = {0}; + char option[NAMEDATALEN]; + const char *short_name = GDALGetDriverShortName(ogr_dr); + + strncpy(stripped_config_options, options, STR_MAX_LEN - 1); + p = strtok(strip_spaces(stripped_config_options), ","); + + while (p != NULL) { + if (strcmp(short_name, "XLSX") == 0 || strcmp(short_name, "XLSX") == 0 || strcmp(short_name, "ODS") == 0) + { + /* Unify the handling of the options of spreadsheet file options as they are all the same except they have their + * Driver Short Name included in the option + */ + sprintf(option, "OGR_%s_%s ", short_name, ogr_fdw_strupr(p)); + } + else { + sprintf(option, "%s ", ogr_fdw_strupr(p)); + } + + strcat(config_options, option); + p = strtok(NULL, ","); + } } - /* There should be a nicer way to do this */ - strcpy(server_name, "myserver"); + option_list = CSLTokenizeString(config_options); + for ( option_iter = option_list; option_iter && *option_iter; option_iter++ ) + { + char *key; + const char *value; + value = CPLParseNameValue(*option_iter, &key); + if (! (key && value)) + CPLError(CE_Failure, CPLE_AppDefined, "bad config option string '%s'", config_options); + + CPLSetConfigOption(key, value); + CPLFree(key); + } + CSLDestroy( option_list ); ogr_lyr = GDALDatasetGetLayerByName(ogr_ds, layer); if (! ogr_lyr) @@ -231,15 +344,25 @@ printf("\nCREATE SERVER %s\n" " FOREIGN DATA WRAPPER ogr_fdw\n" " OPTIONS (\n" - " datasource '%s',\n" - " format '%s' );\n", - server_name, source, GDALGetDriverShortName(ogr_dr)); + " datasource '%s',\n" + " format '%s'", + quote_identifier(server_name), source, GDALGetDriverShortName(ogr_dr)); + + if (strlen(config_options) > 0) + { + printf(",\n config_options '%s');\n", config_options); + } + else + { + printf(");\n"); + } stringbuffer_init(&buf); err = ogrLayerToSQL(ogr_lyr, server_name, TRUE, /* launder table names */ TRUE, /* launder column names */ + table,/* output table name */ TRUE, /* use postgis geometry */ &buf); @@ -255,3 +378,96 @@ return OGRERR_NONE; } +static OGRErr +ogrFindLayer(const char *source, int layerno, const char** layer) +{ + GDALDatasetH ogr_ds = NULL; + int i; + char **option_iter; + char **option_list; + + GDALAllRegister(); + + option_list = CSLTokenizeString(config_options); + for (option_iter = option_list; option_iter && *option_iter; option_iter++) + { + char *key; + const char *value; + value = CPLParseNameValue(*option_iter, &key); + if (! (key && value)) + CPLError(CE_Failure, CPLE_AppDefined, "bad config option string '%s'", config_options); + + CPLSetConfigOption(key, value); + CPLFree(key); + } + CSLDestroy(option_list); + + + #if GDAL_VERSION_MAJOR < 2 + ogr_ds = OGROpen(source, FALSE, NULL); + #else + ogr_ds = GDALOpenEx(source, + GDAL_OF_VECTOR | GDAL_OF_READONLY, + NULL, NULL, NULL); + #endif + + if (! ogr_ds) + { + CPLError(CE_Failure, CPLE_AppDefined, "Could not connect to source '%s'", source); + return OGRERR_FAILURE; + } + + for (i = 0; i < GDALDatasetGetLayerCount(ogr_ds); i++) + { + if (i == layerno) { + OGRLayerH ogr_lyr = GDALDatasetGetLayer(ogr_ds, i); + if (! ogr_lyr) + { + return OGRERR_FAILURE; + } + *layer = OGR_L_GetName(ogr_lyr); + return OGRERR_NONE; + } + } + + GDALClose(ogr_ds); + + return OGRERR_FAILURE; +} + +static int +reserved_word(const char * pgcolumn) +{ + char* reserved[] = { + "all", "analyse", "analyze", "and", "any", "array", "as", "asc", "asymmetric", "authorization", + "binary", "both", + "case", "cast", "check", "collate", "collation", "column", "concurrently", "constraint", "create", "cross", "current_catalog", "current_date", "current_role", + "current_schema", "current_time", "current_timestamp", "current_user", + "default", "deferrable", "desc", "distinct", "do", + "else", "end", "except", + "false", "fetch", "for", "foreign", "freeze", "from", "full", + "grant", "group", + "having", + "ilike", "in", "initially", "inner", "intersect", "into", "is", "isnull", + "join", + "lateral", "leading", "left", "like", "limit", "localtime", "localtimestamp", + "natural", "not", "notnull", "null", + "offset", "on", "only", "or", "order", "outer", "overlaps", + "placing", "primary", + "references", "returning", "right", + "select", "session_user", "similar", "some", "symmetric", + "table", "tablesample", "then", "to", "trailing", "true", + "union", "unique", "user", "using", + "variadic", "verbose", + "when", "where", "window", "with" + }; + + int i; + for (i = 0; i < sizeof(reserved)/sizeof(reserved[0]); i++) + { + if (strcmp(pgcolumn, reserved[i]) == 0) + return 1; + } + + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/output/file.source new/pgsql-ogr-fdw-1.1.0/output/file.source --- old/pgsql-ogr-fdw-1.0.12/output/file.source 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/output/file.source 2021-02-01 18:55:33.000000000 +0100 @@ -102,7 +102,7 @@ SERVER myserver_latin1 OPTIONS ( layer 'enc' ); SET client_min_messages = debug1; -SELECT * FROM e_1 WHERE fid = 1; +SELECT fid, name FROM e_1 WHERE fid = 1; DEBUG: GDAL config option 'SHAPE_ENCODING' set to 'LATIN1' DEBUG: OGR SQL: (fid = 1) DEBUG: GDAL config option 'SHAPE_ENCODING' set to 'LATIN1' @@ -113,6 +113,26 @@ SET client_min_messages = notice; ------------------------------------------------ +-- Using encoding option directly +CREATE SERVER myserver_latin1_direct + FOREIGN DATA WRAPPER ogr_fdw + OPTIONS ( + datasource '@abs_srcdir@/data', + format 'ESRI Shapefile', + character_encoding 'LATIN1' + ); +CREATE FOREIGN TABLE e_2 ( + fid integer, + name varchar ) + SERVER myserver_latin1_direct + OPTIONS ( layer 'enc' ); +SELECT fid, name FROM e_2 WHERE fid = 1; + fid | name +-----+------ + 1 | P??ul +(1 row) + +------------------------------------------------ -- Geometryless test CREATE SERVER csvserver FOREIGN DATA WRAPPER ogr_fdw @@ -160,16 +180,14 @@ popcat integer ) SERVER "fgdbserver" OPTIONS (layer 'Cities'); -SET client_min_messages = DEBUG1; +SET client_min_messages = LOG; SELECT fid, city_name, pop1990 FROM cities WHERE pop1990 = 17710; -DEBUG: OGR SQL: (POP1990 = 17710) fid | city_name | pop1990 -----+--------------+--------- 9 | Port Angeles | 17710 (1 row) SELECT fid, city_name, pop1990 FROM cities WHERE city_name = 'Williston'; -DEBUG: OGR SQL: ("CITY_NAME" = 'Williston') fid | city_name | pop1990 -----+-----------+--------- 8 | Williston | 13131 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pgsql-ogr-fdw-1.0.12/output/pgsql.source new/pgsql-ogr-fdw-1.1.0/output/pgsql.source --- old/pgsql-ogr-fdw-1.0.12/output/pgsql.source 2020-05-25 17:56:02.000000000 +0200 +++ new/pgsql-ogr-fdw-1.1.0/output/pgsql.source 2021-02-01 18:55:33.000000000 +0100 @@ -30,7 +30,7 @@ datasource 'PG:dbname=contrib_regression host=localhost', format 'PostgreSQL' ); CREATE FOREIGN TABLE bytea_fdw ( - fid integer, + fid bigint, geom bytea, name varchar, age bigint, @@ -67,7 +67,7 @@ FROM bytea_fdw; QUERY PLAN ----------------------------------------------------------------------------- - Foreign Scan on public.bytea_fdw (cost=25.00..1025.00 rows=1000 width=166) + Foreign Scan on public.bytea_fdw (cost=25.00..1025.00 rows=1000 width=170) Output: fid, name, geom, age, size, value, num, dt, tm, dttm, varch, yn (2 rows)