mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-04 00:06:46 -05:00
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
This commit is contained in:
commit
ac63c6e645
@ -673,13 +673,14 @@ length, and presents text representations of non numeric/text types (e.g., geome
|
||||
.. versionadded:: 2.14
|
||||
%End
|
||||
|
||||
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value );
|
||||
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType = QVariant::Type::Invalid );
|
||||
%Docstring
|
||||
Create an expression allowing to evaluate if a field is equal to a
|
||||
value. The value may be null.
|
||||
|
||||
:param fieldName: the name of the field
|
||||
:param value: the value of the field
|
||||
: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
|
||||
|
||||
:return: the expression to evaluate field equality
|
||||
|
||||
|
||||
@ -1112,14 +1112,16 @@ QString QgsExpression::formatPreviewString( const QVariant &value, const bool ht
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsExpression::createFieldEqualityExpression( const QString &fieldName, const QVariant &value )
|
||||
QString QgsExpression::createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType )
|
||||
{
|
||||
QString expr;
|
||||
|
||||
if ( value.isNull() )
|
||||
expr = QStringLiteral( "%1 IS NULL" ).arg( quotedColumnRef( fieldName ) );
|
||||
else
|
||||
else if ( fieldType == QVariant::Type::Invalid )
|
||||
expr = QStringLiteral( "%1 = %2" ).arg( quotedColumnRef( fieldName ), quotedValue( value ) );
|
||||
else
|
||||
expr = QStringLiteral( "%1 = %2" ).arg( quotedColumnRef( fieldName ), quotedValue( value, fieldType ) );
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
@ -659,10 +659,11 @@ class CORE_EXPORT QgsExpression
|
||||
* value. The value may be null.
|
||||
* \param fieldName the name of the field
|
||||
* \param value the value of the field
|
||||
* \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
|
||||
* \returns the expression to evaluate field equality
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value );
|
||||
static QString createFieldEqualityExpression( const QString &fieldName, const QVariant &value, QVariant::Type fieldType = QVariant::Type::Invalid );
|
||||
|
||||
/**
|
||||
* Returns TRUE if the given \a expression is a simple "field=value" type expression.
|
||||
|
||||
@ -221,7 +221,16 @@ QString QgsRelation::getRelatedFeaturesFilter( const QgsFeature &feature ) const
|
||||
for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) )
|
||||
{
|
||||
QVariant val( feature.attribute( pair.referencedField() ) );
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val );
|
||||
int referencingIdx = referencingLayer()->fields().lookupField( pair.referencingField() );
|
||||
if ( referencingIdx >= 0 )
|
||||
{
|
||||
QVariant::Type fieldType = referencingLayer()->fields().at( referencingIdx ).type();
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val, fieldType );
|
||||
}
|
||||
else
|
||||
{
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencingField(), val );
|
||||
}
|
||||
}
|
||||
|
||||
return conditions.join( QLatin1String( " AND " ) );
|
||||
@ -233,8 +242,17 @@ QgsFeatureRequest QgsRelation::getReferencedFeatureRequest( const QgsAttributes
|
||||
|
||||
for ( const FieldPair &pair : std::as_const( d->mFieldPairs ) )
|
||||
{
|
||||
int referencedIdx = referencedLayer()->fields().lookupField( pair.referencedField() );
|
||||
int referencingIdx = referencingLayer()->fields().lookupField( pair.referencingField() );
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ) );
|
||||
if ( referencedIdx >= 0 )
|
||||
{
|
||||
QVariant::Type fieldType = referencedLayer()->fields().at( referencedIdx ).type();
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ), fieldType );
|
||||
}
|
||||
else
|
||||
{
|
||||
conditions << QgsExpression::createFieldEqualityExpression( pair.referencedField(), attributes.at( referencingIdx ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsFeatureRequest myRequest;
|
||||
|
||||
@ -271,6 +271,20 @@ class TestQgsExpressionCustomFunctions(unittest.TestCase):
|
||||
res = '"my\'field" = TRUE'
|
||||
self.assertEqual(e.createFieldEqualityExpression(field, value), res)
|
||||
|
||||
# test with field type
|
||||
field = "myfield"
|
||||
value = 1
|
||||
type = QVariant.String
|
||||
res = '"myfield" = \'1\''
|
||||
self.assertEqual(e.createFieldEqualityExpression(field, value, type), res)
|
||||
|
||||
# test with field type
|
||||
field = "myfield"
|
||||
value = "1"
|
||||
type = QVariant.Int
|
||||
res = '"myfield" = 1'
|
||||
self.assertEqual(e.createFieldEqualityExpression(field, value, type), res)
|
||||
|
||||
def testReferencedAttributeIndexesNonExistingField(self):
|
||||
e = QgsExpression()
|
||||
e.setExpression("foo = 1")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user