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 726bac5 commit 0f4cba5
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/providers/postgres/qgspostgresprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3421,16 +3421,16 @@ bool QgsPostgresProvider::convertField( QgsField &field, const QMap<QString, QVa
}

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: 37 additions & 1 deletion tests/src/python/test_provider_postgres.py
Original file line number Diff line number Diff line change
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 @@ -50,11 +54,20 @@ def setUpClass(cls):
assert cls.poly_vl.isValid()
cls.poly_provider = cls.poly_vl.dataProvider()
QgsEditorWidgetRegistry.instance().initEditors()
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('/qgis/compileExpressions', True)

Expand Down Expand Up @@ -424,6 +437,30 @@ def testDoubleArray(self):
self.assertTrue(isinstance(f.attributes()[value_idx], list))
self.assertEqual(f.attributes()[value_idx], [1.1, 2, -5.12345])

# See http://hub.qgis.org/issues/15188
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')


class TestPyQgsPostgresProviderCompoundKey(unittest.TestCase, ProviderTestCase):

Expand Down Expand Up @@ -454,6 +491,5 @@ def uncompiledFilters(self):
def partiallyCompiledFilters(self):
return set([])


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

0 comments on commit 0f4cba5

Please sign in to comment.