Skip to content
Permalink
Browse files
fix #5132
  • Loading branch information
jef-n committed Mar 7, 2012
1 parent e71494a commit 7dc309621829e39fe616c6ebddd85e5a8bd6f8b8
Showing with 50 additions and 35 deletions.
  1. +11 −3 src/core/qgsexpression.cpp
  2. +2 −0 src/core/qgsexpression.h
  3. +8 −6 src/core/qgsexpressionlexer.ll
  4. +22 −24 src/core/qgsexpressionparser.yy
  5. +7 −2 src/gui/qgsexpressionbuilderwidget.cpp
@@ -104,7 +104,7 @@ inline bool isNull( const QVariant& v ) { return v.isNull(); }
const char* QgsExpression::BinaryOperatorText[] =
{
"OR", "AND",
"=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "ILIKE", "IS", "IS NOT",
"=", "<>", "<=", ">=", "<", ">", "~", "LIKE", "NOT LIKE", "ILIKE", "NOT ILIKE", "IS", "IS NOT",
"+", "-", "*", "/", "%", "^",
"||"
};
@@ -722,7 +722,9 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat

case boRegexp:
case boLike:
case boNotLike:
case boILike:
case boNotILike:
if ( isNull( vL ) || isNull( vR ) )
return TVL_Unknown;
else
@@ -731,17 +733,23 @@ QVariant QgsExpression::NodeBinaryOperator::eval( QgsExpression* parent, QgsFeat
QString regexp = getStringValue( vR, parent ); ENSURE_NO_EVAL_ERROR;
// TODO: cache QRegExp in case that regexp is a literal string (i.e. it will stay constant)
bool matches;
if ( mOp == boLike || mOp == boILike ) // change from LIKE syntax to regexp
if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) // change from LIKE syntax to regexp
{
// XXX escape % and _ ???
regexp.replace( "%", ".*" );
regexp.replace( "_", "." );
matches = QRegExp( regexp, mOp == boLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
matches = QRegExp( regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
}
else
{
matches = QRegExp( regexp ).indexIn( str ) != -1;
}

if( mOp == boNotLike || mOp == boNotILike )
{
matches = !matches;
}

return matches ? TVL_True : TVL_False;
}

@@ -149,7 +149,9 @@ class CORE_EXPORT QgsExpression
boGT, // >
boRegexp,
boLike,
boNotLike,
boILike,
boNotILike,
boIs,
boIsNot,

@@ -124,12 +124,14 @@ string "'"{str_char}*"'"
"<" { 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 ILIKE; }
"IS" { B_OP(boIs); return IS; }
"IS NOT" { B_OP(boIsNot); return ISNOT; }
"||" { B_OP(boConcat); return CONCAT; }
"~" { 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; }
@@ -74,7 +74,7 @@ QgsExpression::Node* gExpParserRootNode;
//

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

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

expression:
expression AND expression { $$ = BINOP($2, $1, $3); }
| expression OR expression { $$ = BINOP($2, $1, $3); }
| expression EQ expression { $$ = BINOP($2, $1, $3); }
| expression NE expression { $$ = BINOP($2, $1, $3); }
| expression LE expression { $$ = BINOP($2, $1, $3); }
| expression GE expression { $$ = BINOP($2, $1, $3); }
| expression LT expression { $$ = BINOP($2, $1, $3); }
| expression GT expression { $$ = BINOP($2, $1, $3); }
| expression REGEXP expression { $$ = BINOP($2, $1, $3); }
| expression LIKE expression { $$ = BINOP($2, $1, $3); }
| expression ILIKE expression { $$ = BINOP($2, $1, $3); }
| expression IS expression { $$ = BINOP($2, $1, $3); }
| expression ISNOT expression { $$ = BINOP($2, $1, $3); }
| expression PLUS expression { $$ = BINOP($2, $1, $3); }
| expression MINUS expression { $$ = BINOP($2, $1, $3); }
| expression MUL expression { $$ = BINOP($2, $1, $3); }
| expression DIV expression { $$ = BINOP($2, $1, $3); }
| expression MOD expression { $$ = BINOP($2, $1, $3); }
| expression POW expression { $$ = BINOP($2, $1, $3); }
| expression CONCAT expression { $$ = BINOP($2, $1, $3); }
| NOT expression { $$ = new QgsExpression::NodeUnaryOperator($1, $2); }
| '(' expression ')' { $$ = $2; }
expression AND expression { $$ = BINOP($2, $1, $3); }
| expression OR expression { $$ = BINOP($2, $1, $3); }
| expression EQ expression { $$ = BINOP($2, $1, $3); }
| expression NE expression { $$ = BINOP($2, $1, $3); }
| expression LE expression { $$ = BINOP($2, $1, $3); }
| expression GE expression { $$ = BINOP($2, $1, $3); }
| expression LT expression { $$ = BINOP($2, $1, $3); }
| expression GT expression { $$ = BINOP($2, $1, $3); }
| expression REGEXP expression { $$ = BINOP($2, $1, $3); }
| expression LIKE expression { $$ = BINOP($2, $1, $3); }
| expression IS expression { $$ = BINOP($2, $1, $3); }
| expression PLUS expression { $$ = BINOP($2, $1, $3); }
| expression MINUS expression { $$ = BINOP($2, $1, $3); }
| expression MUL expression { $$ = BINOP($2, $1, $3); }
| expression DIV expression { $$ = BINOP($2, $1, $3); }
| expression MOD expression { $$ = BINOP($2, $1, $3); }
| expression POW expression { $$ = BINOP($2, $1, $3); }
| expression CONCAT expression { $$ = BINOP($2, $1, $3); }
| NOT expression { $$ = new QgsExpression::NodeUnaryOperator($1, $2); }
| '(' expression ')' { $$ = $2; }

| FUNCTION '(' exp_list ')'
{
@@ -180,7 +180,12 @@ void QgsExpressionBuilderWidget::fillFieldValues( int fieldIndex, int countLimit
mLayer->uniqueValues( fieldIndex, values, countLimit );
foreach( QVariant value, values )
{
mValueListWidget->addItem( value.toString() );
if ( value.isNull() )
mValueListWidget->addItem( "NULL" );
else if ( value.type() == QVariant::Int || value.type() == QVariant::Double || value.type() == QVariant::LongLong )
mValueListWidget->addItem( value.toString() );
else
mValueListWidget->addItem( "'" + value.toString().replace( "'", "''" ) + "'" );
}

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

0 comments on commit 7dc3096

Please sign in to comment.