Skip to content

Commit ac63c6e

Browse files
authoredNov 9, 2021
Merge pull request #45841 from 3nids/fix-rel-mismatch-type
improve success of compiled expressions running on backend with mismatching types in relation field pairs
2 parents c1dfea5 + 295a2e9 commit ac63c6e

File tree

5 files changed

+42
-6
lines changed

5 files changed

+42
-6
lines changed
 

‎python/core/auto_generated/expression/qgsexpression.sip.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,13 +673,14 @@ length, and presents text representations of non numeric/text types (e.g., geome
673673
.. versionadded:: 2.14
674674
%End
675675

676-
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value );
676+
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType = QVariant::Type::Invalid );
677677
%Docstring
678678
Create an expression allowing to evaluate if a field is equal to a
679679
value. The value may be null.
680680

681681
:param fieldName: the name of the field
682682
:param value: the value of the field
683+
:param fieldType: the type of the field on the left side used to quote the value. If not given, the value type is used instead
683684

684685
:return: the expression to evaluate field equality
685686

‎src/core/expression/qgsexpression.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,14 +1112,16 @@ QString QgsExpression::formatPreviewString( const QVariant &value, const bool ht
11121112
}
11131113
}
11141114

1115-
QString QgsExpression::createFieldEqualityExpression( const QString &fieldName, const QVariant &value )
1115+
QString QgsExpression::createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType )
11161116
{
11171117
QString expr;
11181118

11191119
if ( value.isNull() )
11201120
expr = QStringLiteral( "%1 IS NULL" ).arg( quotedColumnRef( fieldName ) );
1121-
else
1121+
else if ( fieldType == QVariant::Type::Invalid )
11221122
expr = QStringLiteral( "%1 = %2" ).arg( quotedColumnRef( fieldName ), quotedValue( value ) );
1123+
else
1124+
expr = QStringLiteral( "%1 = %2" ).arg( quotedColumnRef( fieldName ), quotedValue( value, fieldType ) );
11231125

11241126
return expr;
11251127
}

‎src/core/expression/qgsexpression.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,11 @@ class CORE_EXPORT QgsExpression
659659
* value. The value may be null.
660660
* \param fieldName the name of the field
661661
* \param value the value of the field
662+
* \param fieldType the type of the field on the left side used to quote the value. If not given, the value type is used instead
662663
* \returns the expression to evaluate field equality
663664
* \since QGIS 3.0
664665
*/
665-
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value );
666+
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType = QVariant::Type::Invalid );
666667

667668
/**
668669
* Returns TRUE if the given \a expression is a simple "field=value" type expression.

‎src/core/qgsrelation.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,16 @@ QString QgsRelation::getRelatedFeaturesFilter( const QgsFeature &feature ) const
221221
for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) )
222222
{
223223
QVariant val( feature.attribute( pair.referencedField() ) );
224-
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val );
224+
int referencingIdx = referencingLayer()->fields().lookupField( pair.referencingField() );
225+
if ( referencingIdx >= 0 )
226+
{
227+
QVariant::Type fieldType = referencingLayer()->fields().at( referencingIdx ).type();
228+
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val, fieldType );
229+
}
230+
else
231+
{
232+
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val );
233+
}
225234
}
226235

227236
return conditions.join( QLatin1String( " AND " ) );
@@ -233,8 +242,17 @@ QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsAttributes
233242

234243
for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) )
235244
{
245+
int referencedIdx = referencedLayer()->fields().lookupField( pair.referencedField() );
236246
int referencingIdx = referencingLayer()->fields().lookupField( pair.referencingField() );
237-
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ) );
247+
if ( referencedIdx >= 0 )
248+
{
249+
QVariant::Type fieldType = referencedLayer()->fields().at( referencedIdx ).type();
250+
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ), fieldType );
251+
}
252+
else
253+
{
254+
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ) );
255+
}
238256
}
239257

240258
QgsFeatureRequest myRequest;

‎tests/src/python/test_qgsexpression.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,20 @@ def testCreateFieldEqualityExpression(self):
271271
res = '"my\'field" = TRUE'
272272
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
273273

274+
# test with field type
275+
field = "myfield"
276+
value = 1
277+
type = QVariant.String
278+
res = '"myfield" = \'1\''
279+
self.assertEqual(e.createFieldEqualityExpression(field, value, type), res)
280+
281+
# test with field type
282+
field = "myfield"
283+
value = "1"
284+
type = QVariant.Int
285+
res = '"myfield" = 1'
286+
self.assertEqual(e.createFieldEqualityExpression(field, value, type), res)
287+
274288
def testReferencedAttributeIndexesNonExistingField(self):
275289
e = QgsExpression()
276290
e.setExpression("foo = 1")

0 commit comments

Comments
 (0)
Please sign in to comment.