Skip to content

Commit 7dc3096

Browse files
committed
fix #5132
1 parent e71494a commit 7dc3096

5 files changed

+50
-35
lines changed

src/core/qgsexpression.cpp

+11-3
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ inline bool isNull( const QVariant& v ) { return v.isNull(); }
104104
const char* QgsExpression::BinaryOperatorText[] =
105105
{
106106
"OR", "AND",
107-
"=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "ILIKE", "IS", "IS NOT",
107+
"=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "NOT LIKE", "ILIKE", "NOT ILIKE", "IS", "IS NOT",
108108
"+", "-", "*", "/", "%", "^",
109109
"||"
110110
};
@@ -722,7 +722,9 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
722722

723723
case boRegexp:
724724
case boLike:
725+
case boNotLike:
725726
case boILike:
727+
case boNotILike:
726728
if ( isNull( vL ) || isNull( vR ) )
727729
return TVL_Unknown;
728730
else
@@ -731,17 +733,23 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
731733
QString regexp = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
732734
// TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
733735
bool matches;
734-
if ( mOp == boLike || mOp == boILike ) // change from LIKE syntax to regexp
736+
if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) // change from LIKE syntax to regexp
735737
{
736738
// XXX escape % and _ ???
737739
regexp.replace( "%", ".*" );
738740
regexp.replace( "_", "." );
739-
matches = QRegExp( regexp, mOp == boLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
741+
matches = QRegExp( regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
740742
}
741743
else
742744
{
743745
matches = QRegExp( regexp ).indexIn( str ) != -1;
744746
}
747+
748+
if( mOp == boNotLike || mOp == boNotILike )
749+
{
750+
matches = !matches;
751+
}
752+
745753
return matches ? TVL_True : TVL_False;
746754
}
747755

src/core/qgsexpression.h

+2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ class CORE_EXPORT QgsExpression
149149
boGT, // >
150150
boRegexp,
151151
boLike,
152+
boNotLike,
152153
boILike,
154+
boNotILike,
153155
boIs,
154156
boIsNot,
155157

src/core/qgsexpressionlexer.ll

+8-6
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,14 @@ string "'"{str_char}*"'"
124124
"<" { B_OP(boLT); return LT; }
125125
">" { B_OP(boGT); return GT; }
126126
127-
"~" { B_OP(boRegexp); return REGEXP; }
128-
"LIKE" { B_OP(boLike); return LIKE; }
129-
"ILIKE" { B_OP(boILike); return ILIKE; }
130-
"IS" { B_OP(boIs); return IS; }
131-
"IS NOT" { B_OP(boIsNot); return ISNOT; }
132-
"||" { B_OP(boConcat); return CONCAT; }
127+
"~" { B_OP(boRegexp); return REGEXP; }
128+
"LIKE" { B_OP(boLike); return LIKE; }
129+
"NOT LIKE" { B_OP(boNotLike); return LIKE; }
130+
"ILIKE" { B_OP(boILike); return LIKE; }
131+
"NOT ILIKE" { B_OP(boNotILike); return LIKE; }
132+
"IS" { B_OP(boIs); return IS; }
133+
"IS NOT" { B_OP(boIsNot); return IS; }
134+
"||" { B_OP(boConcat); return CONCAT; }
133135
134136
"+" { B_OP(boPlus); return PLUS; }
135137
"-" { B_OP(boMinus); return MINUS; }

src/core/qgsexpressionparser.yy

+22-24
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ QgsExpression::Node* gExpParserRootNode;
7474
//
7575

7676
// operator tokens
77-
%token <b_op> OR AND EQ NE LE GE LT GT REGEXP LIKE ILIKE IS ISNOT PLUS MINUS MUL DIV MOD CONCAT POW
77+
%token <b_op> OR AND EQ NE LE GE LT GT REGEXP LIKE IS PLUS MINUS MUL DIV MOD CONCAT POW
7878
%token <u_op> NOT
7979
%token IN
8080

@@ -114,7 +114,7 @@ QgsExpression::Node* gExpParserRootNode;
114114
%left OR
115115
%left AND
116116
%right NOT
117-
%left EQ NE LE GE LT GT REGEXP LIKE ILIKE IS ISNOT IN
117+
%left EQ NE LE GE LT GT REGEXP LIKE IS IN
118118
%left PLUS MINUS
119119
%left MUL DIV MOD
120120
%right POW
@@ -134,28 +134,26 @@ root: expression { gExpParserRootNode = $1; }
134134
;
135135

136136
expression:
137-
expression AND expression { $$ = BINOP($2, $1, $3); }
138-
| expression OR expression { $$ = BINOP($2, $1, $3); }
139-
| expression EQ expression { $$ = BINOP($2, $1, $3); }
140-
| expression NE expression { $$ = BINOP($2, $1, $3); }
141-
| expression LE expression { $$ = BINOP($2, $1, $3); }
142-
| expression GE expression { $$ = BINOP($2, $1, $3); }
143-
| expression LT expression { $$ = BINOP($2, $1, $3); }
144-
| expression GT expression { $$ = BINOP($2, $1, $3); }
145-
| expression REGEXP expression { $$ = BINOP($2, $1, $3); }
146-
| expression LIKE expression { $$ = BINOP($2, $1, $3); }
147-
| expression ILIKE expression { $$ = BINOP($2, $1, $3); }
148-
| expression IS expression { $$ = BINOP($2, $1, $3); }
149-
| expression ISNOT expression { $$ = BINOP($2, $1, $3); }
150-
| expression PLUS expression { $$ = BINOP($2, $1, $3); }
151-
| expression MINUS expression { $$ = BINOP($2, $1, $3); }
152-
| expression MUL expression { $$ = BINOP($2, $1, $3); }
153-
| expression DIV expression { $$ = BINOP($2, $1, $3); }
154-
| expression MOD expression { $$ = BINOP($2, $1, $3); }
155-
| expression POW expression { $$ = BINOP($2, $1, $3); }
156-
| expression CONCAT expression { $$ = BINOP($2, $1, $3); }
157-
| NOT expression { $$ = new QgsExpression::NodeUnaryOperator($1, $2); }
158-
| '(' expression ')' { $$ = $2; }
137+
expression AND expression { $$ = BINOP($2, $1, $3); }
138+
| expression OR expression { $$ = BINOP($2, $1, $3); }
139+
| expression EQ expression { $$ = BINOP($2, $1, $3); }
140+
| expression NE expression { $$ = BINOP($2, $1, $3); }
141+
| expression LE expression { $$ = BINOP($2, $1, $3); }
142+
| expression GE expression { $$ = BINOP($2, $1, $3); }
143+
| expression LT expression { $$ = BINOP($2, $1, $3); }
144+
| expression GT expression { $$ = BINOP($2, $1, $3); }
145+
| expression REGEXP expression { $$ = BINOP($2, $1, $3); }
146+
| expression LIKE expression { $$ = BINOP($2, $1, $3); }
147+
| expression IS expression { $$ = BINOP($2, $1, $3); }
148+
| expression PLUS expression { $$ = BINOP($2, $1, $3); }
149+
| expression MINUS expression { $$ = BINOP($2, $1, $3); }
150+
| expression MUL expression { $$ = BINOP($2, $1, $3); }
151+
| expression DIV expression { $$ = BINOP($2, $1, $3); }
152+
| expression MOD expression { $$ = BINOP($2, $1, $3); }
153+
| expression POW expression { $$ = BINOP($2, $1, $3); }
154+
| expression CONCAT expression { $$ = BINOP($2, $1, $3); }
155+
| NOT expression { $$ = new QgsExpression::NodeUnaryOperator($1, $2); }
156+
| '(' expression ')' { $$ = $2; }
159157

160158
| FUNCTION '(' exp_list ')'
161159
{

src/gui/qgsexpressionbuilderwidget.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,12 @@ void QgsExpressionBuilderWidget::fillFieldValues( int fieldIndex, int countLimit
180180
mLayer->uniqueValues( fieldIndex, values, countLimit );
181181
foreach( QVariant value, values )
182182
{
183-
mValueListWidget->addItem( value.toString() );
183+
if ( value.isNull() )
184+
mValueListWidget->addItem( "NULL" );
185+
else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
186+
mValueListWidget->addItem( value.toString() );
187+
else
188+
mValueListWidget->addItem( "'" + value.toString().replace( "'", "''" ) + "'" );
184189
}
185190

186191
mValueListWidget->setUpdatesEnabled( true );
@@ -202,7 +207,7 @@ void QgsExpressionBuilderWidget::registerItem( QString group,
202207
}
203208
else
204209
{
205-
// If the group doesn't exsit yet we make it first.
210+
// If the group doesn't exist yet we make it first.
206211
QgsExpressionItem* newgroupNode = new QgsExpressionItem( group, "", QgsExpressionItem::Header );
207212
newgroupNode->appendRow( item );
208213
mModel->appendRow( newgroupNode );

0 commit comments

Comments
 (0)