Skip to content

Commit

Permalink
expression: dump binary operations with brackets to break precedence (f…
Browse files Browse the repository at this point in the history
…ixes #9783)
  • Loading branch information
jef-n committed Mar 14, 2014
1 parent 80c4961 commit b6b78ca
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
50 changes: 49 additions & 1 deletion src/core/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2179,9 +2179,57 @@ bool QgsExpression::NodeBinaryOperator::prepare( QgsExpression* parent, const Qg
return resL && resR;
}

int QgsExpression::NodeBinaryOperator::precedence() const
{
// see left/right in qgsexpressionparser.yy
switch ( mOp )
{
case boOr:
return 1;

case boAnd:
return 2;

case boEQ:
case boNE:
case boLE:
case boGE:
case boLT:
case boGT:
case boRegexp:
case boLike:
case boIs:
case boIsNot:
return 3;

case boPlus:
case boMinus:
return 4;

case boMul:
case boDiv:
case boMod:
return 5;

case boPow:
return 6;

case boConcat:
return 7;
}
}

QString QgsExpression::NodeBinaryOperator::dump() const
{
return QString( "%1 %2 %3" ).arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );

QString fmt;
fmt += lOp && lOp->precedence() < precedence() ? "(%1)" : "%1";
fmt += " %2 ";
fmt += rOp && rOp->precedence() < precedence() ? "(%3)" : "%3";

return fmt.arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
}

//
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsexpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@ class CORE_EXPORT QgsExpression
virtual bool needsGeometry() const { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
virtual void accept( Visitor& v ) const { v.visit( *this ); }

int precedence() const;

protected:
bool compare( double diff );
int computeInt( int x, int y );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayerrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender
if ( !mRendererV2 )
return;

QgsDebugMsg( "rendering v2:\n" + mRendererV2->dump() );
QgsDebugMsg( "rendering v2:\n " + mRendererV2->dump() );

if ( mDrawVertexMarkers )
{
Expand Down
3 changes: 2 additions & 1 deletion src/gui/symbology-ng/qgsdatadefinedsymboldialog.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "qgsdatadefinedsymboldialog.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include <QCheckBox>
#include <QComboBox>
#include <QPushButton>
Expand Down Expand Up @@ -104,7 +105,7 @@ QMap< QString, QString > QgsDataDefinedSymbolDialog::dataDefinedProperties() con

void QgsDataDefinedSymbolDialog::expressionButtonClicked()
{
qWarning( "Expression button clicked" );
QgsDebugMsg( "Expression button clicked" );

//find out row
QObject* senderObj = sender();
Expand Down
12 changes: 12 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,18 @@ class TestQgsExpression: public QObject
}
}

void eval_precedence()
{
QgsExpression e0( "1+2*3" );
QCOMPARE( e0.evaluate().toInt(), 7 );

QgsExpression e1( "(1+2)*(3+4)" );
QCOMPARE( e1.evaluate().toInt(), 21 );

QgsExpression e2( e1.dump() );
QCOMPARE( e2.evaluate().toInt(), 21 );
}

void eval_columns()
{
QgsFields fields;
Expand Down

0 comments on commit b6b78ca

Please sign in to comment.