Skip to content

Commit 4ce2cf1

Browse files
committedSep 21, 2017
[OGR] Add workaround for OGRSQL not recognizing the column name returned by OGR_L_GetFIDColumn
1 parent 6e5324b commit 4ce2cf1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+54
-12
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,26 +3537,51 @@ OGRLayerH QgsOgrProviderUtils::setSubsetString( OGRLayerH layer, GDALDatasetH ds
35373537
layerName = encoding->fromUnicode( modifiedLayerName );
35383538
}
35393539
}
3540-
QByteArray sql;
3540+
OGRLayerH subsetLayer = 0;
35413541
if ( subsetString.startsWith( QLatin1String( "SELECT " ), Qt::CaseInsensitive ) )
3542-
sql = encoding->fromUnicode( subsetString );
3542+
{
3543+
QByteArray sql = encoding->fromUnicode( subsetString );
3544+
3545+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3546+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3547+
}
35433548
else
35443549
{
3550+
QByteArray sqlPart1 = "SELECT ";
3551+
QByteArray sqlPart3 = "* FROM " + quotedIdentifier( layerName, mGDALDriverName )
3552+
+ " WHERE " + encoding->fromUnicode( subsetString );
3553+
3554+
origFidAddAttempted = true;
3555+
35453556
QByteArray fidColumn = OGR_L_GetFIDColumn( layer );
3557+
// Fallback to FID if OGR_L_GetFIDColumn returns nothing
3558+
if ( fidColumn.isEmpty() )
3559+
{
3560+
fidColumn = "FID";
3561+
}
3562+
3563+
QByteArray sql = sqlPart1 + fidColumn + " as orig_ogc_fid, " + sqlPart3;
3564+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3565+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
35463566

3547-
sql = QByteArray( "SELECT " );
3548-
if ( !fidColumn.isEmpty() )
3567+
// See https://lists.osgeo.org/pipermail/qgis-developer/2017-September/049802.html
3568+
// If execute SQL fails because it did not find the fidColumn, retry with hardcoded FID
3569+
if ( !subsetLayer )
35493570
{
3550-
sql += fidColumn + " as orig_ogc_fid, ";
3551-
origFidAddAttempted = true;
3571+
QByteArray sql = sqlPart1 + "FID as orig_ogc_fid, " + sqlPart3;
3572+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3573+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3574+
}
3575+
// If that also fails, just continue without the orig_ogc_fid
3576+
if ( !subsetLayer )
3577+
{
3578+
QByteArray sql = sqlPart1 + sqlPart3;
3579+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3580+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3581+
origFidAddAttempted = false;
35523582
}
3553-
sql += "* FROM " + quotedIdentifier( layerName, mGDALDriverName );
3554-
sql += " WHERE " + encoding->fromUnicode( subsetString );
35553583
}
35563584

3557-
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3558-
OGRLayerH subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3559-
35603585
// Check if first column is orig_ogc_fid
35613586
if ( origFidAddAttempted && subsetLayer )
35623587
{

‎tests/src/python/test_provider_ogr.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import sys
1818
import tempfile
1919

20-
from qgis.core import QgsVectorLayer, QgsVectorDataProvider, QgsWkbTypes
20+
from qgis.core import QgsVectorLayer, QgsVectorDataProvider, QgsWkbTypes, QgsFeature
2121
from qgis.testing import (
2222
start_app,
2323
unittest
@@ -238,6 +238,23 @@ def testGeometryCollection(self):
238238
os.unlink(datasource)
239239
self.assertFalse(os.path.exists(datasource))
240240

241+
def testGdb(self):
242+
""" Test opening a GDB database layer"""
243+
gdb_path = os.path.join(unitTestDataPath(), 'test_gdb.gdb')
244+
for i in range(3):
245+
l = QgsVectorLayer(gdb_path + '|layerid=' + str(i), 'test', 'ogr')
246+
self.assertTrue(l.isValid())
247+
248+
def testGdbFilter(self):
249+
""" Test opening a GDB database layer with filter"""
250+
gdb_path = os.path.join(unitTestDataPath(), 'test_gdb.gdb')
251+
l = QgsVectorLayer(gdb_path + '|layerid=1|subset="text" = \'shape 2\'', 'test', 'ogr')
252+
self.assertTrue(l.isValid())
253+
it = l.getFeatures()
254+
f = QgsFeature()
255+
while it.nextFeature(f):
256+
self.assertTrue(f.attribute("text") == "shape 2")
257+
241258

242259
if __name__ == '__main__':
243260
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.