Skip to content

Commit

Permalink
Fix bogus precision/scale in PostgreSQL for double values
Browse files Browse the repository at this point in the history
This reverts commit 92f71b6,
which broke import of legit shapefiles by assuming wrong
semantic for the non-constraining QgsField length/precision
attributes.

Closes #15188

Includes test
  • Loading branch information
strk committed Oct 12, 2016
1 parent edd56e9 commit a985d8c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/providers/postgres/qgspostgresprovider.cpp
Expand Up @@ -3440,16 +3440,16 @@ bool QgsPostgresProvider::convertField( QgsField &field, const QMap<QString, QVa
break;

case QVariant::Double:
if ( fieldPrec > 0 )
if ( fieldSize > 18 )
{
fieldType = "numeric";
fieldSize = -1;
}
else
{
fieldType = "float8";
fieldSize = -1;
fieldPrec = -1;
}
fieldPrec = -1;
break;

default:
Expand Down
38 changes: 38 additions & 0 deletions tests/src/python/test_provider_postgres.py
Expand Up @@ -14,11 +14,15 @@
__revision__ = '$Format:%H$'

import qgis # NOQA
import psycopg2

import os

from qgis.core import (
QgsGeometry,
QgsPoint,
QgsVectorLayer,
QgsVectorLayerImport,
QgsFeatureRequest,
QgsFeature,
QgsTransactionGroup,
Expand Down Expand Up @@ -48,11 +52,20 @@ def setUpClass(cls):
cls.poly_vl = QgsVectorLayer(cls.dbconn + ' sslmode=disable key=\'pk\' srid=4326 type=POLYGON table="qgis_test"."some_poly_data" (geom) sql=', 'test', 'postgres')
assert cls.poly_vl.isValid()
cls.poly_provider = cls.poly_vl.dataProvider()
cls.con = psycopg2.connect(cls.dbconn)

@classmethod
def tearDownClass(cls):
"""Run after all tests"""

def execSQLCommand(self, sql):
self.assertTrue(self.con)
cur = self.con.cursor()
self.assertTrue(cur)
cur.execute(sql)
cur.close()
self.con.commit()

def enableCompiler(self):
QSettings().setValue(u'/qgis/compileExpressions', True)

Expand Down Expand Up @@ -312,5 +325,30 @@ def testRenameAttributes(self):
self.assertEqual(fet.fields()[1].name(), 'newname2')
self.assertEqual(fet.fields()[2].name(), 'another')

# See http://hub.qgis.org/issues/18155
def testNumericPrecision(self):
uri = 'point?field=f1:int'
uri += '&field=f2:double(6,4)'
uri += '&field=f3:string(20)'
lyr = QgsVectorLayer(uri, "x", "memory")
self.assertTrue(lyr.isValid())
f = QgsFeature(lyr.fields())
f['f1'] = 1
f['f2'] = 123.456
f['f3'] = '12345678.90123456789'
lyr.dataProvider().addFeatures([f])
uri = '%s table="qgis_test"."b18155" (g) key=\'f1\'' % (self.dbconn)
self.execSQLCommand('DROP TABLE IF EXISTS qgis_test.b18155')
err = QgsVectorLayerImport.importLayer(lyr, uri, "postgres", lyr.crs())
self.assertEqual(err[0], QgsVectorLayerImport.NoError,
'unexpected import error {0}'.format(err))
lyr = QgsVectorLayer(uri, "y", "postgres")
self.assertTrue(lyr.isValid())
f = next(lyr.getFeatures())
self.assertEqual(f['f1'], 1)
self.assertEqual(f['f2'], 123.456)
self.assertEqual(f['f3'], '12345678.90123456789')


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

0 comments on commit a985d8c

Please sign in to comment.