Skip to content

Commit

Permalink
[expressions] Fix fetching joined column refs when expression is
Browse files Browse the repository at this point in the history
not prepared (fix #14746)
  • Loading branch information
nyalldawson committed May 2, 2016
1 parent d3fcdb4 commit febe30d
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/core/qgsexpression.cpp
Expand Up @@ -4283,11 +4283,23 @@ QgsExpression::Node*QgsExpression::NodeLiteral::clone() const
QVariant QgsExpression::NodeColumnRef::eval( QgsExpression *parent, const QgsExpressionContext *context )
{
Q_UNUSED( parent );
int index = mIndex;

if ( index < 0 )
{
// have not yet found field index - first check explicitly set fields collection
if ( context->hasVariable( QgsExpressionContext::EXPR_FIELDS ) )
{
QgsFields fields = qvariant_cast<QgsFields>( context->variable( QgsExpressionContext::EXPR_FIELDS ) );
index = fields.fieldNameIndex( mName );
}
}

if ( context && context->hasVariable( QgsExpressionContext::EXPR_FEATURE ) )
{
QgsFeature feature = qvariant_cast<QgsFeature>( context->variable( QgsExpressionContext::EXPR_FEATURE ) );
if ( mIndex >= 0 )
return feature.attribute( mIndex );
if ( index >= 0 )
return feature.attribute( index );
else
return feature.attribute( mName );
}
Expand Down
41 changes: 41 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -2101,6 +2101,47 @@ class TestQgsExpression: public QObject
QgsExpression nodeExpression( "1 IN (1, 2, 3, 4)" );
QgsExpression nodeExpression2( nodeExpression );
}

void test_columnRefUnprepared()
{
//test retrieving fields from feature when expression is unprepared - explicitly specified fields collection
//should take precedence over feature's field collection

QgsFields fields;
fields.append( QgsField( "f1", QVariant::String ) );

QgsFeature f( 1 );
f.setFields( fields );

//also add a joined field - this will not be available in feature's field collection
fields.append( QgsField( "j1", QVariant::String ), QgsFields::OriginJoin, 1 );

f.setAttributes( QgsAttributes() << QVariant( "f1" ) << QVariant( "j1" ) );
f.setValid( true );

QgsExpression e( "\"f1\"" );
QgsExpressionContext context;
context.setFeature( f );
context.setFields( fields );
QVariant result = e.evaluate( &context );
QCOMPARE( result.toString(), QString( "f1" ) );

//test joined field
QgsExpression e2( "\"j1\"" );
result = e2.evaluate( &context );
QCOMPARE( result.toString(), QString( "j1" ) );

// final test - check that feature's field collection is also used when corresponding field NOT found
// in explicitly passed field collection
fields.append( QgsField( "f2", QVariant::String ) );
f.setFields( fields );
f.setAttributes( QgsAttributes() << QVariant( "f1" ) << QVariant( "j1" ) << QVariant( "f2" ) );
context.setFeature( f );
QgsExpression e3( "\"f2\"" );
result = e3.evaluate( &context );
QCOMPARE( result.toString(), QString( "f2" ) );
}

};

QTEST_MAIN( TestQgsExpression )
Expand Down

0 comments on commit febe30d

Please sign in to comment.