diff --git a/src/providers/postgres/qgspostgresprovider.cpp b/src/providers/postgres/qgspostgresprovider.cpp index 4221cf8b5416..584a91dc6156 100644 --- a/src/providers/postgres/qgspostgresprovider.cpp +++ b/src/providers/postgres/qgspostgresprovider.cpp @@ -4609,13 +4609,15 @@ Qgis::VectorExportResult QgsPostgresProvider::createEmptyLayer( const QString &u { pkList = parseUriKey( primaryKey ); const auto constPkList = pkList; + const bool lowercaseFieldNames = options && options->value( QStringLiteral( "lowercaseFieldNames" ), false ).toBool(); for ( const QString &col : constPkList ) { // search for the passed field QString type; for ( int fldIdx = 0; fldIdx < fields.count(); ++fldIdx ) { - if ( fields[fldIdx].name() == col ) + const QString fieldName = lowercaseFieldNames ? fields[fldIdx].name().toLower() : fields[fldIdx].name(); + if ( fieldName == col ) { // found, get the field type QgsField fld = fields[fldIdx]; diff --git a/tests/src/python/test_provider_postgres.py b/tests/src/python/test_provider_postgres.py index 7d533159d79e..ac370084bb27 100644 --- a/tests/src/python/test_provider_postgres.py +++ b/tests/src/python/test_provider_postgres.py @@ -3266,6 +3266,50 @@ def testGeographyAddFeature(self): self.assertTrue(dp.addFeature(f)) self.assertEqual(vl.featureCount(), 1) + # See: https://github.com/qgis/QGIS/issues/55856 + def testPktLowerCase(self): + # check that primary key creation correctly works + # when exporting a vector layer to postgresql with + # lowercaseFieldNames option set to True + + # create an empty vector layer + pk_key = "DEP" + input_uri = f"NoGeometry?crs=&field={pk_key}:string(255,0)&field=REG:string(255,0)&field=Number:integer(10,0)" + layer = QgsVectorLayer(input_uri, "lowercase", "memory") + self.assertTrue(layer.isValid()) + + # export the vector layer to postgresql with lowercase field names + self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.pk_lowercase') + output_uri = f'{self.dbconn} table="qgis_test"."pk_lowercase" key=\'{pk_key.lower()}\'' + err = QgsVectorLayerExporter.exportLayer(layer, output_uri, "postgres", layer.crs(), False, {'lowercaseFieldNames': True}) + self.assertEqual(err[0], QgsVectorLayerExporter.ExportError.NoError, + f'unexpected import error {err}') + + # retrieve the columns and type and check them + cur = self.con.cursor() + sql_cols = ( + "SELECT column_name, data_type FROM information_schema.columns " + "WHERE table_name = 'pk_lowercase' AND table_schema = 'qgis_test';" + ) + cur.execute(sql_cols) + expected_cols = [ + ('dep', 'character varying'), + ('reg', 'character varying'), + ('number', 'integer')] + self.assertEqual(cur.fetchall(), expected_cols) + + # Retrieve the primary key and check its name and type + sql_pk = ( + "SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type " + "FROM pg_index i " + "JOIN pg_attribute a ON a.attrelid = i.indrelid " + "AND a.attnum = ANY(i.indkey) " + "WHERE i.indrelid = 'qgis_test.pk_lowercase'::regclass " + "AND i.indisprimary;" + ) + cur.execute(sql_pk) + self.assertEqual(cur.fetchall(), [('dep', 'character varying')]) + class TestPyQgsPostgresProviderCompoundKey(QgisTestCase, ProviderTestCase):