Skip to content

Commit

Permalink
[FEATURE] support NULL values in search strings (fixes #2533)
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13023 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Mar 8, 2010
1 parent 38bc285 commit 687bf26
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/core/qgssearchstringlexer.ll
Expand Up @@ -59,6 +59,10 @@ string "'"{str_char}*"'"
"AND" { return AND; } "AND" { return AND; }
"OR" { return OR; } "OR" { return OR; }


"NULL" { return NULLVALUE; }

"IS" { return IS; }

"=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; } "=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; }
"!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; } "!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; }
"<=" { yylval.op = QgsSearchTreeNode::opLE; return COMPARISON; } "<=" { yylval.op = QgsSearchTreeNode::opLE; return COMPARISON; }
Expand Down
12 changes: 8 additions & 4 deletions src/core/qgssearchstringparser.yy
Expand Up @@ -62,8 +62,10 @@ void addToTmpNodes(QgsSearchTreeNode* node);
%token <number> NUMBER %token <number> NUMBER
%token <op> COMPARISON %token <op> COMPARISON
%token <op> FUNCTION %token <op> FUNCTION
%token IS
%token AREA %token AREA
%token LENGTH %token LENGTH
%token NULLVALUE


%token STRING %token STRING
%token COLUMN_REF %token COLUMN_REF
Expand Down Expand Up @@ -119,12 +121,14 @@ predicate:
; ;


comp_predicate: comp_predicate:
scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); } scalar_exp IS NULLVALUE { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opISNULL, $1, 0); joinTmpNodes($$,$1,0); }
| scalar_exp IS NOT NULLVALUE { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opISNOTNULL, $1, 0); joinTmpNodes($$,$1,0); }
| scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
; ;


scalar_exp: scalar_exp:
FUNCTION '(' scalar_exp ')' {$$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);} FUNCTION '(' scalar_exp ')' { $$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); } | scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
| scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); } | scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); } | scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); } | scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
Expand All @@ -134,7 +138,7 @@ scalar_exp:
| '-' scalar_exp %prec UMINUS { $$ = $2; if ($$->type() == QgsSearchTreeNode::tNumber) $$->setNumber(- $$->number()); } | '-' scalar_exp %prec UMINUS { $$ = $2; if ($$->type() == QgsSearchTreeNode::tNumber) $$->setNumber(- $$->number()); }
| AREA { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opAREA, 0, 0); addToTmpNodes($$); } | AREA { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opAREA, 0, 0); addToTmpNodes($$); }
| LENGTH { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opLENGTH, 0, 0); addToTmpNodes($$); } | LENGTH { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opLENGTH, 0, 0); addToTmpNodes($$); }
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); } | NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
| STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); } | STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); }
| COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); } | COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); }
; ;
Expand Down
27 changes: 26 additions & 1 deletion src/core/qgssearchtreenode.cpp
Expand Up @@ -237,6 +237,20 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
return true; return true;
return mRight->checkAgainst( fields, attributes ); return mRight->checkAgainst( fields, attributes );


case opISNULL:
case opISNOTNULL:
if ( !getValue( value1, mLeft, fields, attributes ) )
return false;

if ( mOp == opISNULL )
{
return value1.isNull();
}
else if ( mOp == opISNOTNULL )
{
return !value1.isNull();
}

case opEQ: case opEQ:
case opNE: case opNE:
case opGT: case opGT:
Expand All @@ -247,6 +261,12 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
if ( !getValue( value1, mLeft, fields, attributes ) || !getValue( value2, mRight, fields, attributes ) ) if ( !getValue( value1, mLeft, fields, attributes ) || !getValue( value2, mRight, fields, attributes ) )
return false; return false;


if ( value1.isNull() || value2.isNull() )
{
// NULL values never match
return false;
}

res = QgsSearchTreeValue::compare( value1, value2 ); res = QgsSearchTreeValue::compare( value1, value2 );


switch ( mOp ) switch ( mOp )
Expand Down Expand Up @@ -365,7 +385,12 @@ QgsSearchTreeValue QgsSearchTreeNode::valueAgainst( const QgsFieldMap& fields, c


// get the value // get the value
QVariant val = attributes[it.key()]; QVariant val = attributes[it.key()];
if ( val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double ) if ( val.isNull() )
{
QgsDebugMsgLevel( " NULL", 2 );
return QgsSearchTreeValue();
}
else if ( val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double )
{ {
QgsDebugMsgLevel( " number: " + QString::number( val.toDouble() ), 2 ); QgsDebugMsgLevel( " number: " + QString::number( val.toDouble() ), 2 );
return QgsSearchTreeValue( val.toDouble() ); return QgsSearchTreeValue( val.toDouble() );
Expand Down
10 changes: 7 additions & 3 deletions src/core/qgssearchtreenode.h
Expand Up @@ -78,6 +78,8 @@ class CORE_EXPORT QgsSearchTreeNode
opAREA, opAREA,


// comparison // comparison
opISNULL, // IS NULL
opISNOTNULL, // IS NOT NULL
opEQ, // = opEQ, // =
opNE, // != resp. <> opNE, // != resp. <>
opGT, // > opGT, // >
Expand Down Expand Up @@ -174,11 +176,12 @@ class CORE_EXPORT QgsSearchTreeValue
{ {
valError, valError,
valString, valString,
valNumber valNumber,
valNull
}; };


QgsSearchTreeValue() { } QgsSearchTreeValue() { mType = valNull; }
QgsSearchTreeValue( QString string ) { mType = valString; mString = string; } QgsSearchTreeValue( QString string ) { mType = string.isNull() ? valNull : valString; mString = string; }
QgsSearchTreeValue( double number ) { mType = valNumber; mNumber = number; } QgsSearchTreeValue( double number ) { mType = valNumber; mNumber = number; }
QgsSearchTreeValue( int error, QString errorMsg ) { mType = valError; mNumber = error; mString = errorMsg; } QgsSearchTreeValue( int error, QString errorMsg ) { mType = valError; mNumber = error; mString = errorMsg; }


Expand All @@ -187,6 +190,7 @@ class CORE_EXPORT QgsSearchTreeValue


bool isNumeric() { return mType == valNumber; } bool isNumeric() { return mType == valNumber; }
bool isError() { return mType == valError; } bool isError() { return mType == valError; }
bool isNull() { return mType == valNull; }


QString& string() { return mString; } QString& string() { return mString; }
double number() { return mNumber; } double number() { return mNumber; }
Expand Down

0 comments on commit 687bf26

Please sign in to comment.