Skip to content

Commit

Permalink
When creating a expression filter string for a rule based renderer,
Browse files Browse the repository at this point in the history
try to create a simple "field IN (...)" expression wherever possible

This avoids some issues with complex rule based renderers that have
many similar classes, where the generated expression was previously
an extremely long and complex "(field = ...) OR (field = ...) OR ..."
type expression (which some providers have issues with)

Fixes missing features in some circumstances in rule based renderers

Sponsored by SLYR
  • Loading branch information
nyalldawson committed Jan 12, 2021
1 parent 44c2a26 commit 9e9d247
Showing 1 changed file with 30 additions and 22 deletions.
52 changes: 30 additions & 22 deletions src/core/symbology/qgsrulebasedrenderer.cpp
Expand Up @@ -453,31 +453,39 @@ bool QgsRuleBasedRenderer::Rule::startRender( QgsRenderContext &context, const Q
{
sf = QStringLiteral( "TRUE" );
}
// If we have more than 50 rules (to stay on the safe side) make a binary tree or SQLITE will fail,
// see: https://github.com/qgis/QGIS/issues/27269
else if ( subfilters.count() > 50 )
else
{
std::function<QString( const QStringList & )>bt = [ &bt ]( const QStringList & subf )
// test for a common case -- all subfilters can be combined into a single "field in (...)" expression
if ( QgsExpression::attemptReduceToInClause( subfilters, sf ) )
{
if ( subf.count( ) == 1 )
{
return subf.at( 0 );
}
else if ( subf.count( ) == 2 )
{
return subf.join( QLatin1String( ") OR (" ) ).prepend( '(' ).append( ')' );
}
else
// success! we can use a simple "field IN (...)" list!
}
// If we have more than 50 rules (to stay on the safe side) make a binary tree or SQLITE will fail,
// see: https://github.com/qgis/QGIS/issues/27269
else if ( subfilters.count() > 50 )
{
std::function<QString( const QStringList & )>bt = [ &bt ]( const QStringList & subf )
{
int midpos = static_cast<int>( subf.length() / 2 );
return QStringLiteral( "(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ) ).arg( bt( subf.mid( midpos ) ) );
}
};
sf = bt( subfilters );
}
else
{
sf = subfilters.join( QLatin1String( ") OR (" ) ).prepend( '(' ).append( ')' );
if ( subf.count( ) == 1 )
{
return subf.at( 0 );
}
else if ( subf.count( ) == 2 )
{
return subf.join( QLatin1String( ") OR (" ) ).prepend( '(' ).append( ')' );
}
else
{
int midpos = static_cast<int>( subf.length() / 2 );
return QStringLiteral( "(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ), bt( subf.mid( midpos ) ) );
}
};
sf = bt( subfilters );
}
else
{
sf = subfilters.join( QLatin1String( ") OR (" ) ).prepend( '(' ).append( ')' );
}
}
}

Expand Down

0 comments on commit 9e9d247

Please sign in to comment.