Skip to content

Commit 687bf26

Browse files
author
jef
committed
[FEATURE] support NULL values in search strings (fixes #2533)
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13023 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 38bc285 commit 687bf26

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

src/core/qgssearchstringlexer.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ string "'"{str_char}*"'"
5959
"AND" { return AND; }
6060
"OR" { return OR; }
6161

62+
"NULL" { return NULLVALUE; }
63+
64+
"IS" { return IS; }
65+
6266
"=" { yylval.op = QgsSearchTreeNode::opEQ; return COMPARISON; }
6367
"!=" { yylval.op = QgsSearchTreeNode::opNE; return COMPARISON; }
6468
"<=" { yylval.op = QgsSearchTreeNode::opLE; return COMPARISON; }

src/core/qgssearchstringparser.yy

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ void addToTmpNodes(QgsSearchTreeNode* node);
6262
%token <number> NUMBER
6363
%token <op> COMPARISON
6464
%token <op> FUNCTION
65+
%token IS
6566
%token AREA
6667
%token LENGTH
68+
%token NULLVALUE
6769

6870
%token STRING
6971
%token COLUMN_REF
@@ -119,12 +121,14 @@ predicate:
119121
;
120122

121123
comp_predicate:
122-
scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
124+
scalar_exp IS NULLVALUE { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opISNULL, $1, 0); joinTmpNodes($$,$1,0); }
125+
| scalar_exp IS NOT NULLVALUE { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opISNOTNULL, $1, 0); joinTmpNodes($$,$1,0); }
126+
| scalar_exp COMPARISON scalar_exp { $$ = new QgsSearchTreeNode($2, $1, $3); joinTmpNodes($$,$1,$3); }
123127
;
124128

125129
scalar_exp:
126-
FUNCTION '(' scalar_exp ')' {$$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
127-
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
130+
FUNCTION '(' scalar_exp ')' { $$ = new QgsSearchTreeNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
131+
| scalar_exp '^' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPOW, $1, $3); joinTmpNodes($$, $1, $3); }
128132
| scalar_exp '*' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
129133
| scalar_exp '/' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
130134
| scalar_exp '+' scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
@@ -134,7 +138,7 @@ scalar_exp:
134138
| '-' scalar_exp %prec UMINUS { $$ = $2; if ($$->type() == QgsSearchTreeNode::tNumber) $$->setNumber(- $$->number()); }
135139
| AREA { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opAREA, 0, 0); addToTmpNodes($$); }
136140
| LENGTH { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opLENGTH, 0, 0); addToTmpNodes($$); }
137-
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
141+
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
138142
| STRING { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 0); addToTmpNodes($$); }
139143
| COLUMN_REF { $$ = new QgsSearchTreeNode(QString::fromUtf8(yytext), 1); addToTmpNodes($$); }
140144
;

src/core/qgssearchtreenode.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,20 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
237237
return true;
238238
return mRight->checkAgainst( fields, attributes );
239239

240+
case opISNULL:
241+
case opISNOTNULL:
242+
if ( !getValue( value1, mLeft, fields, attributes ) )
243+
return false;
244+
245+
if ( mOp == opISNULL )
246+
{
247+
return value1.isNull();
248+
}
249+
else if ( mOp == opISNOTNULL )
250+
{
251+
return !value1.isNull();
252+
}
253+
240254
case opEQ:
241255
case opNE:
242256
case opGT:
@@ -247,6 +261,12 @@ bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttrib
247261
if ( !getValue( value1, mLeft, fields, attributes ) || !getValue( value2, mRight, fields, attributes ) )
248262
return false;
249263

264+
if ( value1.isNull() || value2.isNull() )
265+
{
266+
// NULL values never match
267+
return false;
268+
}
269+
250270
res = QgsSearchTreeValue::compare( value1, value2 );
251271

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

366386
// get the value
367387
QVariant val = attributes[it.key()];
368-
if ( val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double )
388+
if ( val.isNull() )
389+
{
390+
QgsDebugMsgLevel( " NULL", 2 );
391+
return QgsSearchTreeValue();
392+
}
393+
else if ( val.type() == QVariant::Bool || val.type() == QVariant::Int || val.type() == QVariant::Double )
369394
{
370395
QgsDebugMsgLevel( " number: " + QString::number( val.toDouble() ), 2 );
371396
return QgsSearchTreeValue( val.toDouble() );

src/core/qgssearchtreenode.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class CORE_EXPORT QgsSearchTreeNode
7878
opAREA,
7979

8080
// comparison
81+
opISNULL, // IS NULL
82+
opISNOTNULL, // IS NOT NULL
8183
opEQ, // =
8284
opNE, // != resp. <>
8385
opGT, // >
@@ -174,11 +176,12 @@ class CORE_EXPORT QgsSearchTreeValue
174176
{
175177
valError,
176178
valString,
177-
valNumber
179+
valNumber,
180+
valNull
178181
};
179182

180-
QgsSearchTreeValue() { }
181-
QgsSearchTreeValue( QString string ) { mType = valString; mString = string; }
183+
QgsSearchTreeValue() { mType = valNull; }
184+
QgsSearchTreeValue( QString string ) { mType = string.isNull() ? valNull : valString; mString = string; }
182185
QgsSearchTreeValue( double number ) { mType = valNumber; mNumber = number; }
183186
QgsSearchTreeValue( int error, QString errorMsg ) { mType = valError; mNumber = error; mString = errorMsg; }
184187

@@ -187,6 +190,7 @@ class CORE_EXPORT QgsSearchTreeValue
187190

188191
bool isNumeric() { return mType == valNumber; }
189192
bool isError() { return mType == valError; }
193+
bool isNull() { return mType == valNull; }
190194

191195
QString& string() { return mString; }
192196
double number() { return mNumber; }

0 commit comments

Comments
 (0)