Skip to content

Commit e09946a

Browse files
committedSep 20, 2017
[OGR] Add workaround for OGRSQL not recognizing the column name returned by OGR_L_GetFIDColumn
1 parent 36e6bd1 commit e09946a

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

+56
-13
lines changed
 

‎src/providers/ogr/qgsogrprovider.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,26 +3443,51 @@ OGRLayerH QgsOgrProviderUtils::setSubsetString( OGRLayerH layer, OGRDataSourceH
34433443
layerName = encoding->fromUnicode( modifiedLayerName );
34443444
}
34453445
}
3446-
QByteArray sql;
3447-
if ( subsetString.startsWith( "SELECT ", Qt::CaseInsensitive ) )
3448-
sql = encoding->fromUnicode( subsetString );
3446+
OGRLayerH subsetLayer = 0;
3447+
if ( subsetString.startsWith( QLatin1String( "SELECT " ), Qt::CaseInsensitive ) )
3448+
{
3449+
QByteArray sql = encoding->fromUnicode( subsetString );
3450+
3451+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3452+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3453+
}
34493454
else
34503455
{
3456+
QByteArray sqlPart1 = "SELECT ";
3457+
QByteArray sqlPart3 = "* FROM " + quotedIdentifier( layerName, ogrDriverName )
3458+
+ " WHERE " + encoding->fromUnicode( subsetString );
3459+
3460+
origFidAddAttempted = true;
3461+
34513462
QByteArray fidColumn = OGR_L_GetFIDColumn( layer );
3463+
// Fallback to FID if OGR_L_GetFIDColumn returns nothing
3464+
if ( fidColumn.isEmpty() )
3465+
{
3466+
fidColumn = "FID";
3467+
}
3468+
3469+
QByteArray sql = sqlPart1 + fidColumn + " as orig_ogc_fid, " + sqlPart3;
3470+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3471+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
34523472

3453-
sql = QByteArray( "SELECT " );
3454-
if ( !fidColumn.isEmpty() )
3473+
// See https://lists.osgeo.org/pipermail/qgis-developer/2017-September/049802.html
3474+
// If execute SQL fails because it did not find the fidColumn, retry with hardcoded FID
3475+
if ( !subsetLayer )
34553476
{
3456-
sql += fidColumn + " as orig_ogc_fid, ";
3457-
origFidAddAttempted = true;
3477+
QByteArray sql = sqlPart1 + "FID as orig_ogc_fid, " + sqlPart3;
3478+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3479+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3480+
}
3481+
// If that also fails, just continue without the orig_ogc_fid
3482+
if ( !subsetLayer )
3483+
{
3484+
QByteArray sql = sqlPart1 + sqlPart3;
3485+
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3486+
subsetLayer = GDALDatasetExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3487+
origFidAddAttempted = false;
34583488
}
3459-
sql += "* FROM " + quotedIdentifier( layerName, ogrDriverName );
3460-
sql += " WHERE " + encoding->fromUnicode( subsetString );
34613489
}
34623490

3463-
QgsDebugMsg( QString( "SQL: %1" ).arg( encoding->toUnicode( sql ) ) );
3464-
OGRLayerH subsetLayer = OGR_DS_ExecuteSQL( ds, sql.constData(), nullptr, nullptr );
3465-
34663491
// Check if first column is orig_ogc_fid
34673492
if ( origFidAddAttempted && subsetLayer )
34683493
{

‎tests/src/python/test_provider_ogr.py

Lines changed: 19 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
@@ -240,5 +240,23 @@ def testGeometryCollection(self):
240240
os.unlink(datasource)
241241
self.assertFalse(os.path.exists(datasource))
242242

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

0 commit comments

Comments
 (0)
Please sign in to comment.