Skip to content

Commit 9da341a

Browse files
author
wonder
committedJul 20, 2010
Support string concatenation using the standard sql concatenation operator ||
Developed for Faunalia (http://www.faunalia.it) with funding from Regione Toscana - Sistema Informativo per la Gestione del Territorio e dell' Ambiente [RT-SIGTA]. For the project: "Sviluppo di prodotti software GIS open-source basati sui prodotti QuantumGIS e Postgis (CIG 037728516E)" git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13940 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

5 files changed

+42
-2
lines changed

5 files changed

+42
-2
lines changed
 

‎python/core/qgssearchtreenode.sip

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,13 @@ class QgsSearchTreeNode
3636
opASIN,
3737
opACOS,
3838
opATAN,
39+
40+
// conversion
3941
opTOINT,
4042
opTOREAL,
4143
opTOSTRING,
44+
45+
// measuring
4246
opLENGTH,
4347
opAREA,
4448

@@ -50,7 +54,10 @@ class QgsSearchTreeNode
5054
opGE, // >=
5155
opLE, // <=
5256
opRegexp, // ~
53-
opLike // LIKE
57+
opLike, // LIKE
58+
59+
// string handling
60+
opCONCAT
5461
};
5562

5663
//! constructors

‎src/core/qgssearchstringlexer.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ string "'"{str_char}*"'"
9292
"to real" { yylval.op = QgsSearchTreeNode::opTOREAL; return FUNCTION;}
9393
"to string" { yylval.op = QgsSearchTreeNode::opTOSTRING; return FUNCTION;}
9494
95+
"||" { return CONCAT; }
96+
9597
[+-/*^] { return yytext[0]; }
9698
9799
[()] { return yytext[0]; }

‎src/core/qgssearchstringparser.yy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
6262
%token <number> NUMBER
6363
%token <op> COMPARISON
6464
%token <op> FUNCTION
65+
%token CONCAT
6566
%token IS
6667
%token AREA
6768
%token LENGTH
@@ -95,6 +96,8 @@ void addToTmpNodes(QgsSearchTreeNode* node);
9596

9697
%left COMPARISON
9798

99+
%left CONCAT
100+
98101
%left '+' '-'
99102
%left '*' '/'
100103
%left '^'
@@ -136,6 +139,7 @@ scalar_exp:
136139
| '(' scalar_exp ')' { $$ = $2; }
137140
| '+' scalar_exp %prec UMINUS { $$ = $2; }
138141
| '-' scalar_exp %prec UMINUS { $$ = $2; if ($$->type() == QgsSearchTreeNode::tNumber) $$->setNumber(- $$->number()); }
142+
| scalar_exp CONCAT scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opCONCAT, $1, $3); joinTmpNodes($$, $1, $3); }
139143
| AREA { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opAREA, 0, 0); addToTmpNodes($$); }
140144
| LENGTH { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opLENGTH, 0, 0); addToTmpNodes($$); }
141145
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }

‎src/core/qgssearchtreenode.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ QString QgsSearchTreeNode::makeSearchString()
214214
case opRegexp: str += " ~ "; break;
215215
case opLike: str += " LIKE "; break;
216216

217+
// TODO: other opeators / functions
218+
case opCONCAT: str += " || "; break;
219+
217220
default: str += " ? ";
218221
}
219222

@@ -548,12 +551,29 @@ QgsSearchTreeValue QgsSearchTreeNode::valueAgainst( const QgsFieldMap& fields, c
548551
//don't convert to numbers in case of string concatenation
549552
if ( mLeft && mRight && !value1.isNumeric() && !value2.isNumeric() )
550553
{
554+
// TODO: concatenation using '+' operator should be removed in favor of '||' operator
555+
// because it may lead to surprising behavior if numbers are stored in a string
551556
if ( mOp == opPLUS )
552557
{
553558
return QgsSearchTreeValue( value1.string() + value2.string() );
554559
}
555560
}
556561

562+
// string concatenation ||
563+
if ( mLeft && mRight && mOp == opCONCAT )
564+
{
565+
if ( value1.isNumeric() && value2.isNumeric() )
566+
{
567+
return QgsSearchTreeValue( 5, "Operator doesn't match the argument types." );
568+
}
569+
else
570+
{
571+
QString arg1 = value1.isNumeric() ? QString::number( value1.number() ) : value1.string();
572+
QString arg2 = value2.isNumeric() ? QString::number( value2.number() ) : value2.string();
573+
return QgsSearchTreeValue( arg1 + arg2 );
574+
}
575+
}
576+
557577
// for other operators, convert strings to numbers if needed
558578
double val1, val2;
559579
if ( value1.isNumeric() )

‎src/core/qgssearchtreenode.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,13 @@ class CORE_EXPORT QgsSearchTreeNode
7272
opASIN,
7373
opACOS,
7474
opATAN,
75+
76+
// conversion
7577
opTOINT,
7678
opTOREAL,
7779
opTOSTRING,
80+
81+
// measuring
7882
opLENGTH,
7983
opAREA,
8084

@@ -88,7 +92,10 @@ class CORE_EXPORT QgsSearchTreeNode
8892
opGE, // >=
8993
opLE, // <=
9094
opRegexp, // ~
91-
opLike // LIKE
95+
opLike, // LIKE
96+
97+
// string handling
98+
opCONCAT
9299
};
93100

94101
//! constructors

0 commit comments

Comments
 (0)
Please sign in to comment.