From b51426640dd61cf0bb18ebad680c96ac16f9b435 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Sat, 2 Feb 2019 11:45:13 +0100 Subject: [PATCH] Quote field name identifiers in ORDER BY and MAX/MIN queries Fixes #21100 --- src/providers/ogr/qgsogrprovider.cpp | 8 ++++---- tests/src/python/test_provider_ogr_gpkg.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/providers/ogr/qgsogrprovider.cpp b/src/providers/ogr/qgsogrprovider.cpp index d9884c9ede2..c0adcbe473e 100644 --- a/src/providers/ogr/qgsogrprovider.cpp +++ b/src/providers/ogr/qgsogrprovider.cpp @@ -3604,7 +3604,7 @@ QSet QgsOgrProvider::uniqueValues( int index, int limit ) const sql += " WHERE " + textEncoding()->fromUnicode( mSubsetString ); } - sql += " ORDER BY " + textEncoding()->fromUnicode( fld.name() ) + " ASC"; // quoting of fieldname produces a syntax error + sql += " ORDER BY " + quotedIdentifier( textEncoding()->fromUnicode( fld.name() ) ) + " ASC"; QgsDebugMsg( QStringLiteral( "SQL: %1" ).arg( textEncoding()->toUnicode( sql ) ) ); QgsOgrLayerUniquePtr l = mOgrLayer->ExecuteSQL( sql ); @@ -3649,7 +3649,7 @@ QStringList QgsOgrProvider::uniqueStringsMatching( int index, const QString &sub sql += " AND (" + textEncoding()->fromUnicode( mSubsetString ) + ')'; } - sql += " ORDER BY " + textEncoding()->fromUnicode( fld.name() ) + " ASC"; // quoting of fieldname produces a syntax error + sql += " ORDER BY " + quotedIdentifier( textEncoding()->fromUnicode( fld.name() ) ) + " ASC"; QgsDebugMsg( QStringLiteral( "SQL: %1" ).arg( textEncoding()->toUnicode( sql ) ) ); QgsOgrLayerUniquePtr l = mOgrLayer->ExecuteSQL( sql ); @@ -3681,7 +3681,7 @@ QVariant QgsOgrProvider::minimumValue( int index ) const QgsField fld = mAttributeFields.at( index ); // Don't quote column name (see https://trac.osgeo.org/gdal/ticket/5799#comment:9) - QByteArray sql = "SELECT MIN(" + textEncoding()->fromUnicode( fld.name() ); + QByteArray sql = "SELECT MIN(" + quotedIdentifier( textEncoding()->fromUnicode( fld.name() ) ); sql += ") FROM " + quotedIdentifier( mOgrLayer->name() ); if ( !mSubsetString.isEmpty() ) @@ -3715,7 +3715,7 @@ QVariant QgsOgrProvider::maximumValue( int index ) const QgsField fld = mAttributeFields.at( index ); // Don't quote column name (see https://trac.osgeo.org/gdal/ticket/5799#comment:9) - QByteArray sql = "SELECT MAX(" + textEncoding()->fromUnicode( fld.name() ); + QByteArray sql = "SELECT MAX(" + quotedIdentifier( textEncoding()->fromUnicode( fld.name() ) ); sql += ") FROM " + quotedIdentifier( mOgrLayer->name() ); if ( !mSubsetString.isEmpty() ) diff --git a/tests/src/python/test_provider_ogr_gpkg.py b/tests/src/python/test_provider_ogr_gpkg.py index d9502d7e571..977640e0005 100644 --- a/tests/src/python/test_provider_ogr_gpkg.py +++ b/tests/src/python/test_provider_ogr_gpkg.py @@ -1293,6 +1293,16 @@ class TestPyQgsOGRProviderGpkg(unittest.TestCase): self.assertNotEqual(vl.fields().indexFromName('json_content2'), -1) self.assertEqual(vl.fields().indexFromName('json_content3'), -1) + def test_quote_identifier(self): + """Regression #21100""" + + tmpfile = os.path.join(self.basetestpath, 'bug21100-wierd_field_names.gpkg') + shutil.copy(os.path.join(unitTestDataPath(''), 'bug21100-wierd_field_names.gpkg'), tmpfile) + vl = QgsVectorLayer('{}|layerid=0'.format(tmpfile), 'foo', 'ogr') + self.assertTrue(vl.isValid()) + for i in range(1, len(vl.fields())): + self.assertEqual(vl.uniqueValues(i), {'a', 'b', 'c'}) + if __name__ == '__main__': unittest.main()