Skip to content
Permalink
Browse files

[oracle] Fix feature request when expression compilation fails,

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 d089cbaaa6a51ca54414c7ea817539bb51862c72
Showing with 64 additions and 21 deletions.
  1. +63 −20 src/providers/oracle/qgsoraclefeatureiterator.cpp
  2. +1 −1 src/providers/oracle/qgsoraclefeatureiterator.h
@@ -61,7 +61,7 @@ QgsOracleFeatureIterator::QgsOracleFeatureIterator( QgsOracleFeatureSource* sour
else
mAttributeList = mSource->mFields.allAttributesList();


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

if ( !mSource->mGeometryColumn.isNull() )
@@ -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:
@@ -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()
@@ -392,7 +432,7 @@ bool QgsOracleFeatureIterator::close()
return true;
}

bool QgsOracleFeatureIterator::openQuery( QString whereClause )
bool QgsOracleFeatureIterator::openQuery( QString whereClause, bool showLog )
{
try
{
@@ -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;
}
}
@@ -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;

0 comments on commit d089cba

Please sign in to comment.
You can’t perform that action at this time.