Skip to content

Commit b6b78ca

Browse files
committed
expression: dump binary operations with brackets to break precedence (fixes #9783)
1 parent 80c4961 commit b6b78ca

File tree

5 files changed

+66
-3
lines changed

5 files changed

+66
-3
lines changed

src/core/qgsexpression.cpp

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2179,9 +2179,57 @@ bool QgsExpression::NodeBinaryOperator::prepare( QgsExpression* parent, const Qg
21792179
return resL && resR;
21802180
}
21812181

2182+
int QgsExpression::NodeBinaryOperator::precedence() const
2183+
{
2184+
// see left/right in qgsexpressionparser.yy
2185+
switch ( mOp )
2186+
{
2187+
case boOr:
2188+
return 1;
2189+
2190+
case boAnd:
2191+
return 2;
2192+
2193+
case boEQ:
2194+
case boNE:
2195+
case boLE:
2196+
case boGE:
2197+
case boLT:
2198+
case boGT:
2199+
case boRegexp:
2200+
case boLike:
2201+
case boIs:
2202+
case boIsNot:
2203+
return 3;
2204+
2205+
case boPlus:
2206+
case boMinus:
2207+
return 4;
2208+
2209+
case boMul:
2210+
case boDiv:
2211+
case boMod:
2212+
return 5;
2213+
2214+
case boPow:
2215+
return 6;
2216+
2217+
case boConcat:
2218+
return 7;
2219+
}
2220+
}
2221+
21822222
QString QgsExpression::NodeBinaryOperator::dump() const
21832223
{
2184-
return QString( "%1 %2 %3" ).arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
2224+
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
2225+
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );
2226+
2227+
QString fmt;
2228+
fmt += lOp && lOp->precedence() < precedence() ? "(%1)" : "%1";
2229+
fmt += " %2 ";
2230+
fmt += rOp && rOp->precedence() < precedence() ? "(%3)" : "%3";
2231+
2232+
return fmt.arg( mOpLeft->dump() ).arg( BinaryOperatorText[mOp] ).arg( mOpRight->dump() );
21852233
}
21862234

21872235
//

src/core/qgsexpression.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,8 @@ class CORE_EXPORT QgsExpression
441441
virtual bool needsGeometry() const { return mOpLeft->needsGeometry() || mOpRight->needsGeometry(); }
442442
virtual void accept( Visitor& v ) const { v.visit( *this ); }
443443

444+
int precedence() const;
445+
444446
protected:
445447
bool compare( double diff );
446448
int computeInt( int x, int y );

src/core/qgsvectorlayerrenderer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ QgsVectorLayerRenderer::QgsVectorLayerRenderer( QgsVectorLayer* layer, QgsRender
6868
if ( !mRendererV2 )
6969
return;
7070

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

7373
if ( mDrawVertexMarkers )
7474
{

src/gui/symbology-ng/qgsdatadefinedsymboldialog.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "qgsdatadefinedsymboldialog.h"
22
#include "qgsexpressionbuilderdialog.h"
33
#include "qgsvectorlayer.h"
4+
#include "qgslogger.h"
45
#include <QCheckBox>
56
#include <QComboBox>
67
#include <QPushButton>
@@ -104,7 +105,7 @@ QMap< QString, QString > QgsDataDefinedSymbolDialog::dataDefinedProperties() con
104105

105106
void QgsDataDefinedSymbolDialog::expressionButtonClicked()
106107
{
107-
qWarning( "Expression button clicked" );
108+
QgsDebugMsg( "Expression button clicked" );
108109

109110
//find out row
110111
QObject* senderObj = sender();

tests/src/core/testqgsexpression.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,18 @@ class TestQgsExpression: public QObject
432432
}
433433
}
434434

435+
void eval_precedence()
436+
{
437+
QgsExpression e0( "1+2*3" );
438+
QCOMPARE( e0.evaluate().toInt(), 7 );
439+
440+
QgsExpression e1( "(1+2)*(3+4)" );
441+
QCOMPARE( e1.evaluate().toInt(), 21 );
442+
443+
QgsExpression e2( e1.dump() );
444+
QCOMPARE( e2.evaluate().toInt(), 21 );
445+
}
446+
435447
void eval_columns()
436448
{
437449
QgsFields fields;

0 commit comments

Comments
 (0)