Skip to content

Commit

Permalink
[oracle] Fix feature request when expression compilation fails,
Browse files Browse the repository at this point in the history
fix incorrect provider side use of limit when expression compilation
could not be used

On behalf of Faunalia, sponsored by ENEL
  • Loading branch information
nyalldawson committed Jul 6, 2016
1 parent 369e130 commit d089cba
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 21 deletions.
83 changes: 63 additions & 20 deletions src/providers/oracle/qgsoraclefeatureiterator.cpp
Expand Up @@ -61,7 +61,7 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* sour
else
mAttributeList = mSource->mFields.allAttributesList();


bool limitAtProvider = ( mRequest.limit() >= 0 );
QString whereClause;

if ( !mSource->mGeometryColumn.isNull() )
Expand Down Expand Up @@ -139,15 +139,7 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* sour
break;

case QgsFeatureRequest::FilterExpression:
if ( QSettings().value( "/qgis/compileExpressions", true ).toBool() )
{
QgsOracleExpressionCompiler compiler( mSource );
if ( compiler.compile( mRequest.filterExpression() ) == QgsSqlExpressionCompiler::Complete )
{
whereClause = QgsOracleUtils::andWhereClauses( whereClause, compiler.result() );
mExpressionCompiled = true;
}
}
//handled below
break;

case QgsFeatureRequest::FilterRect:
Expand All @@ -163,22 +155,70 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* sour
whereClause += QgsOracleConn::databaseTypeFilter( "FEATUREREQUEST", mSource->mGeometryColumn, mSource->mRequestedGeomType );
}

if ( mRequest.limit() >= 0 )
if ( !mSource->mSqlWhereClause.isEmpty() )
{
if ( !whereClause.isEmpty() )
whereClause += " AND ";
whereClause += "(" + mSource->mSqlWhereClause + ")";
}

whereClause += QString( "rownum<=%1" ).arg( mRequest.limit() );
//NOTE - must be last added!
mExpressionCompiled = false;
mCompileStatus = NoCompilation;
QString fallbackStatement;
bool useFallback = false;
if ( request.filterType() == QgsFeatureRequest::FilterExpression )
{
if ( QSettings().value( "/qgis/compileExpressions", true ).toBool() )
{
QgsOracleExpressionCompiler compiler( mSource );
QgsSqlExpressionCompiler::Result result = compiler.compile( mRequest.filterExpression() );
if ( result == QgsSqlExpressionCompiler::Complete || result == QgsSqlExpressionCompiler::Partial )
{
fallbackStatement = whereClause;
useFallback = true;
whereClause = QgsOracleUtils::andWhereClauses( whereClause, compiler.result() );

//if only partial success when compiling expression, we need to double-check results using QGIS' expressions
mExpressionCompiled = ( result == QgsSqlExpressionCompiler::Complete );
mCompileStatus = ( mExpressionCompiled ? Compiled : PartiallyCompiled );
limitAtProvider = mExpressionCompiled;
}
else
{
limitAtProvider = false;
}
}
else
{
limitAtProvider = false;
}
}

if ( !mSource->mSqlWhereClause.isEmpty() )
if ( !mRequest.orderBy().isEmpty() )
{
limitAtProvider = false;
}

if ( mRequest.limit() >= 0 && limitAtProvider )
{
if ( !whereClause.isEmpty() )
whereClause += " AND ";
whereClause += "(" + mSource->mSqlWhereClause + ")";

whereClause += QString( "rownum<=%1" ).arg( mRequest.limit() );
fallbackStatement += QString( "rownum<=%1" ).arg( mRequest.limit() );
}

openQuery( whereClause );
bool result = openQuery( whereClause, !useFallback );
if ( !result && useFallback )
{
result = openQuery( fallbackStatement );
if ( result )
{
mExpressionCompiled = false;
mCompileStatus = NoCompilation;
}
}
}

QgsOracleFeatureIterator::~QgsOracleFeatureIterator()
Expand Down Expand Up @@ -392,7 +432,7 @@ bool QgsOracleFeatureIterator::close()
return true;
}

bool QgsOracleFeatureIterator::openQuery( QString whereClause )
bool QgsOracleFeatureIterator::openQuery( QString whereClause, bool showLog )
{
try
{
Expand Down Expand Up @@ -447,10 +487,13 @@ bool QgsOracleFeatureIterator::openQuery( QString whereClause )
mSql = query;
if ( !QgsOracleProvider::exec( mQry, query ) )
{
QgsMessageLog::logMessage( QObject::tr( "Fetching features failed.\nSQL:%1\nError: %2" )
.arg( mQry.lastQuery() )
.arg( mQry.lastError().text() ),
QObject::tr( "Oracle" ) );
if ( showLog )
{
QgsMessageLog::logMessage( QObject::tr( "Fetching features failed.\nSQL:%1\nError: %2" )
.arg( mQry.lastQuery() )
.arg( mQry.lastError().text() ),
QObject::tr( "Oracle" ) );
}
return false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/providers/oracle/qgsoraclefeatureiterator.h
Expand Up @@ -76,7 +76,7 @@ class QgsOracleFeatureIterator : public QgsAbstractFeatureIteratorFromSource<Qgs
//! fetch next feature filter expression
bool nextFeatureFilterExpression( QgsFeature& f ) override;

bool openQuery( QString whereClause );
bool openQuery( QString whereClause, bool showLog = true );

QgsOracleConn *mConnection;
QSqlQuery mQry;
Expand Down

0 comments on commit d089cba

Please sign in to comment.