Skip to content

Commit 81be559

Browse files
committedMar 3, 2016
Fix OGR expression compiler with GDAL >= 2.0
Some extreme corner cases (eg "NULL OR TRUE") tested by the provider tests were failing with GDAL 2.0. In GDAL<2.0 these expressions would be rejected by OGR, but it seems GDAL>=2.0 has partial support for these so the expression compiler needs to handle them before handing off to GDAL.
1 parent 4dbd884 commit 81be559

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed
 

‎src/core/qgssqlexpressioncompiler.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,22 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
162162
break;
163163

164164
case QgsExpression::boOr:
165+
if ( mFlags.testFlag( NoNullInBooleanLogic ) )
166+
{
167+
if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
168+
return Fail;
169+
}
170+
165171
op = "OR";
166172
break;
167173

168174
case QgsExpression::boAnd:
175+
if ( mFlags.testFlag( NoNullInBooleanLogic ) )
176+
{
177+
if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
178+
return Fail;
179+
}
180+
169181
op = "AND";
170182
break;
171183

@@ -297,3 +309,12 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
297309

298310
return Fail;
299311
}
312+
313+
bool QgsSqlExpressionCompiler::nodeIsNullLiteral( const QgsExpression::Node* node ) const
314+
{
315+
if ( node->nodeType() != QgsExpression::ntLiteral )
316+
return false;
317+
318+
const QgsExpression::NodeLiteral* nLit = static_cast<const QgsExpression::NodeLiteral*>( node );
319+
return nLit->value().isNull();
320+
}

‎src/core/qgssqlexpressioncompiler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class CORE_EXPORT QgsSqlExpressionCompiler
4949
{
5050
CaseInsensitiveStringMatch = 0x01, //!< Provider performs case-insensitive string matching for all strings
5151
LikeIsCaseInsensitive = 0x02, //!< Provider treats LIKE as case-insensitive
52+
NoNullInBooleanLogic = 0x04, //!< Provider does not support using NULL with boolean logic, eg "(...) OR NULL"
5253
};
5354
Q_DECLARE_FLAGS( Flags, Flag )
5455

@@ -98,6 +99,8 @@ class CORE_EXPORT QgsSqlExpressionCompiler
9899

99100
Flags mFlags;
100101

102+
bool nodeIsNullLiteral( const QgsExpression::Node* node ) const;
103+
101104
};
102105

103106
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsSqlExpressionCompiler::Flags )

‎src/providers/ogr/qgsogrexpressioncompiler.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include "qgsogrprovider.h"
1818

1919
QgsOgrExpressionCompiler::QgsOgrExpressionCompiler( QgsOgrFeatureSource* source )
20-
: QgsSqlExpressionCompiler( source->mFields, QgsSqlExpressionCompiler::CaseInsensitiveStringMatch )
20+
: QgsSqlExpressionCompiler( source->mFields, QgsSqlExpressionCompiler::CaseInsensitiveStringMatch | QgsSqlExpressionCompiler::NoNullInBooleanLogic )
2121
, mSource( source )
2222
{
2323
}
@@ -95,5 +95,12 @@ QString QgsOgrExpressionCompiler::quotedIdentifier( const QString& identifier )
9595
QString QgsOgrExpressionCompiler::quotedValue( const QVariant& value, bool& ok )
9696
{
9797
ok = true;
98+
99+
if ( value.type() == QVariant::Bool )
100+
{
101+
// No support for boolean literals, so fake them
102+
return value.toBool() ? "(1=1)" : "(1=0)";
103+
}
104+
98105
return QgsOgrProviderUtils::quotedValue( value );
99106
}

0 commit comments

Comments
 (0)
Please sign in to comment.