[QGIS-Developer] OGR/GBD: Unrecognized field name OBJECTID (was: Re: Warning - possible project corruption in 2.18.13)
Even Rouault
even.rouault at spatialys.com
Wed Sep 20 03:46:38 PDT 2017
On mercredi 20 septembre 2017 11:34:50 CEST Sandro Mani wrote:
> On 20.09.2017 08:45, Nyall Dawson wrote:
> > On 20 September 2017 at 10:18, Nyall Dawson <nyall.dawson at gmail.com> wrote:
> >> Hi all,
> >>
> >> I've just been trying to diagnose an issue with loading an existing
> >> 2.18 project in the new 2.18.13 release.
> >>
> >> Seems like something may be broken here with regards to loading OGR
> >> based layers which have a subset filter set.
> >>
> >> These layers trigger the "missing layers" dialog when loading the
> >> project and the layer link cannot be repaired without removing the
> >> filter clause.
> >>
> >> (specifically this is with .gdb layers on Windows - not sure yet if
> >> it's restricted to this combination).
> >>
> >> So just a heads up to test your existing projects before rolling out
> >> the 2.18.13 update.
> >
> > Failing unit test is here: https://github.com/qgis/QGIS/pull/5222,
> > regression bisected to https://github.com/qgis/QGIS/commit/8eaeaaa
> >
> > Sandro can you take a look at this?
>
> Argh.
>
> So the result of the subset query
>
> SELECT OBJECTID as orig_ogc_fid, * FROM "lines" WHERE "text" = 'shape 2'
>
> now is
>
> 305: OGR(1): OGR[3] error 1: Unrecognized field name OBJECTID.
> 305: OGR(1): Data source is invalid (Unrecognized field name OBJECTID.)
>
> but OBJECTID is what was returned by
>
> OGR_L_GetFIDColumn( layer )
<long_story>
Ah, that one is tricky. Let me try to explain the situation
Normally when you do ExecuteSQL(sql_statement, NULL, dialect) with dialect==NULL, OGR
will forward sql_statement to the underlying SQL engine for a SQL compatible DBMS
(Postgres, MySQL, SQLite, OCI, etc....), and if there's no such engine, evaluate it with its own
OGRSQL builtin engine.
For the FileGDB driver, the ESRI SDK has some SQL evaluation capability, but my testing
showed that it was too limited to be reliable, so by default I fallback to OGRSQL.
You can force the use of the ESRI SQL engine by specifying a dialect == "FileGDB". If you do
that with the above statement, you'll get
$ ogrinfo sampleFGDB_1.gdb -sql "select OBJECTID as foo, * FROM polygonArcsZM1" -
dialect FileGDB -q
ERROR 1: Failed at executing 'select OBJECTID as foo, * FROM polygonArcsZM1' (An invalid
SQL statement was used.)
So no better. Apparently, the ESRI SDK doesn't like selecting a column and "*".
So to come back to the bug, the SQL statement is evaluated with the OGRSQL engine. So this
is a bug in it in the situation where the FID column name is an actual non-empty string.
OGRSQL only understands "FID" as the shortcut for whatever the FID column name, and
doesn't try to look if a column name matches OGR_L_GetFIDColumn() (when it was
developped, all drivers that defaulted to OGRSQL had an implementation of
OGR_L_GetFIDColumn() that returned a "" string). So this is a current shortcoming of the
OGRSQL engine, that should probably be fixed
In the meantime you have to workaround it on the QGIS side, both for the "FileGDB" and
"OpenFileGDB" drivers (. In that situation instead of using the result of
OGR_L_GetFIDColumn() to build your SQL statement, hardcode FID.
So your statement will become:
SELECT FID as orig_ogc_fid, * FROM "lines" WHERE "text" = 'shape 2'
Actually when digging a bit more this could affect also the GeoJSON driver, but not in all
situations. Only if you have a "id" member at the same level of "type": "Feature"
So something like
{ "type": "Feature", "id": 168, "properties": {...}, "geometry": {...} "
then id will be used as the FID and returned by OGR_L_GetFIDColumn()
And you'll hit the FileGDB bug
If you have something like
{ "type": "Feature", "properties": { "id": 168,...}, "geometry": {...} "
Then OGR_L_GetFIDColumn() will return "id" but you'll have also a regular id field, so
"SELECT id as ogrig_ogc_fid, * FROM ..." will work then.
</long_story>
<short_answer>
My (final!) suggestion is thus to first try:
SELECT {OGR_L_GetFIDColumn() or FID if it is empty} as orig_ogc_fid, * FROM
If that returns an error look for CPLGetLastErrorMsg() and if it contains
OGR_L_GetFIDColumn() in it, retry with
SELECT FID as orig_ogc_fid, * FROM
Not pretty, but should be relatively robust
</sort_answer>
Even
--
Spatialys - Geospatial professional services
http://www.spatialys.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/qgis-developer/attachments/20170920/611738f7/attachment-0001.html>
More information about the QGIS-Developer
mailing list