Skip to content

Commit

Permalink
fix parsing of IS NOT and NOT LIKE, NOT ILIKE and dumping of IS (NOT …
Browse files Browse the repository at this point in the history
…...) (fixes #13938)
  • Loading branch information
jef-n committed Feb 14, 2016
1 parent b7a9634 commit 5d989ab
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/app/qgswelcomepage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ QgsWelcomePage::QgsWelcomePage( QWidget* parent )
mVersionInformation->setVisible( false );

mVersionInfo = new QgsVersionInfo();
if( !QgsApplication::isRunningFromBuildDir() )
if ( !QgsApplication::isRunningFromBuildDir() )
{
connect( mVersionInfo, SIGNAL( versionInfoAvailable() ), this, SLOT( versionInfoReceived() ) );
mVersionInfo->checkVersion();
Expand Down
11 changes: 10 additions & 1 deletion src/core/qgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4004,6 +4004,15 @@ QString QgsExpression::NodeBinaryOperator::dump() const
{
QgsExpression::NodeBinaryOperator *lOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpLeft );
QgsExpression::NodeBinaryOperator *rOp = dynamic_cast<QgsExpression::NodeBinaryOperator *>( mOpRight );
QgsExpression::NodeUnaryOperator *ruOp = dynamic_cast<QgsExpression::NodeUnaryOperator *>( mOpRight );

QString rdump( mOpRight->dump() );

// avoid dumping "IS (NOT ...)" as "IS NOT ..."
if ( mOp == boIs && ruOp && ruOp->op() == uoNot )
{
rdump.prepend( '(' ).append( ')' );
}

QString fmt;
if ( leftAssociative() )
Expand All @@ -4019,7 +4028,7 @@ QString QgsExpression::NodeBinaryOperator::dump() const
fmt += rOp && ( rOp->precedence() < precedence() ) ? "(%3)" : "%3";
}

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

QgsExpression::Node* QgsExpression::NodeBinaryOperator::clone() const
Expand Down
63 changes: 30 additions & 33 deletions src/core/qgsexpressionlexer.ll
Original file line number Diff line number Diff line change
Expand Up @@ -136,44 +136,41 @@ string "'"{str_char}*"'"
"AND" { B_OP(boAnd); return AND; }
"OR" { B_OP(boOr); return OR; }
"=" { B_OP(boEQ); return EQ; }
"!=" { B_OP(boNE); return NE; }
"<=" { B_OP(boLE); return LE; }
">=" { B_OP(boGE); return GE; }
"<>" { B_OP(boNE); return NE; }
"<" { B_OP(boLT); return LT; }
">" { B_OP(boGT); return GT; }
"~" { B_OP(boRegexp); return REGEXP; }
"LIKE" { B_OP(boLike); return LIKE; }
"NOT LIKE" { B_OP(boNotLike); return LIKE; }
"ILIKE" { B_OP(boILike); return LIKE; }
"NOT ILIKE" { B_OP(boNotILike); return LIKE; }
"IS" { B_OP(boIs); return IS; }
"IS NOT" { B_OP(boIsNot); return IS; }
"||" { B_OP(boConcat); return CONCAT; }
"+" { B_OP(boPlus); return PLUS; }
"-" { B_OP(boMinus); return MINUS; }
"*" { B_OP(boMul); return MUL; }
"//" { B_OP(boIntDiv); return INTDIV; }
"/" { B_OP(boDiv); return DIV; }
"%" { B_OP(boMod); return MOD; }
"^" { B_OP(boPow); return POW; }
"IN" { return IN; }
"=" { B_OP(boEQ); return EQ; }
"!=" { B_OP(boNE); return NE; }
"<=" { B_OP(boLE); return LE; }
">=" { B_OP(boGE); return GE; }
"<>" { B_OP(boNE); return NE; }
"<" { B_OP(boLT); return LT; }
">" { B_OP(boGT); return GT; }
"~" { B_OP(boRegexp); return REGEXP; }
"LIKE" { B_OP(boLike); return LIKE; }
"ILIKE" { B_OP(boILike); return LIKE; }
"IS" { B_OP(boIs); return IS; }
"||" { B_OP(boConcat); return CONCAT; }
"+" { B_OP(boPlus); return PLUS; }
"-" { B_OP(boMinus); return MINUS; }
"*" { B_OP(boMul); return MUL; }
"//" { B_OP(boIntDiv); return INTDIV; }
"/" { B_OP(boDiv); return DIV; }
"%" { B_OP(boMod); return MOD; }
"^" { B_OP(boPow); return POW; }
"IN" { return IN; }
"NULL" { return NULLVALUE; }
"CASE" { return CASE; }
"WHEN" { return WHEN; }
"THEN" { return THEN; }
"ELSE" { return ELSE; }
"END" { return END; }
"CASE" { return CASE; }
"WHEN" { return WHEN; }
"THEN" { return THEN; }
"ELSE" { return ELSE; }
"END" { return END; }
[()] { return yytext[0]; }
[()] { return yytext[0]; }
"," { return COMMA; }
"," { return COMMA; }
{num_float} { yylval->numberFloat = cLocale.toDouble( QString::fromAscii(yytext) ); return NUMBER_FLOAT; }
{num_int} {
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgsexpressionparser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,9 @@ expression:
| expression GT expression { $$ = BINOP($2, $1, $3); }
| expression REGEXP expression { $$ = BINOP($2, $1, $3); }
| expression LIKE expression { $$ = BINOP($2, $1, $3); }
| expression NOT LIKE expression { $$ = BINOP($3==QgsExpression::boLike ? QgsExpression::boNotLike : QgsExpression::boNotILike, $1, $4); }
| expression IS expression { $$ = BINOP($2, $1, $3); }
| expression IS NOT expression { $$ = BINOP(QgsExpression::boIsNot, $1, $4); }
| expression PLUS expression { $$ = BINOP($2, $1, $3); }
| expression MINUS expression { $$ = BINOP($2, $1, $3); }
| expression MUL expression { $$ = BINOP($2, $1, $3); }
Expand Down
11 changes: 9 additions & 2 deletions tests/src/core/testqgsexpression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,15 @@ class TestQgsExpression: public QObject
QTest::newRow( "feature to bool true" ) << QString( "case when get_feature('test','col1',10) then true else false end" ) << false << QVariant( true );
QTest::newRow( "geometry to bool false" ) << QString( "case when geom_from_wkt('') then true else false end" ) << false << QVariant( false );
QTest::newRow( "geometry to bool true" ) << QString( "case when geom_from_wkt('Point(3 4)') then true else false end" ) << false << QVariant( true );

// is not
QTest::newRow( "1 is (not 2)" ) << QString( "1 is (not 2)" ) << false << QVariant( 0 );
QTest::newRow( "1 is not 2" ) << QString( "1 is not 2" ) << false << QVariant( 1 );
QTest::newRow( "1 is not 2" ) << QString( "1 is not 2" ) << false << QVariant( 1 );

// not like
QTest::newRow( "'a' not like 'a%'" ) << QString( "'a' not like 'a%'" ) << false << QVariant( 0 );
QTest::newRow( "'a' not like 'a%'" ) << QString( "'a' not like 'a%'" ) << false << QVariant( 0 );
}

void run_evaluation_test( QgsExpression& exp, bool evalError, QVariant& expected )
Expand Down Expand Up @@ -872,7 +881,6 @@ class TestQgsExpression: public QObject
{
QCOMPARE( QgsExpression::BinaryOperatorText[QgsExpression::boDiv], "/" );
QCOMPARE( QgsExpression::BinaryOperatorText[QgsExpression::boConcat], "||" );

}

void eval_columns()
Expand Down Expand Up @@ -1893,7 +1901,6 @@ class TestQgsExpression: public QObject
// This mainly should not crash, root node should have outlived the original one
QVERIFY( !expcopy.rootNode()->dump().isEmpty() );


// Let's take another copy
QgsExpression expcopy2( expcopy );

Expand Down

0 comments on commit 5d989ab

Please sign in to comment.