Skip to content
Permalink
Browse files
Support string concatenation using the standard sql concatenation ope…
…rator ||

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
  • Loading branch information
wonder committed Jul 20, 2010
1 parent 8b066a0 commit 9da341a334fdb82f543d0fa2618f133e53cf81f3
Showing with 42 additions and 2 deletions.
  1. +8 −1 python/core/qgssearchtreenode.sip
  2. +2 −0 src/core/qgssearchstringlexer.ll
  3. +4 −0 src/core/qgssearchstringparser.yy
  4. +20 −0 src/core/qgssearchtreenode.cpp
  5. +8 −1 src/core/qgssearchtreenode.h
@@ -36,9 +36,13 @@ class QgsSearchTreeNode
opASIN,
opACOS,
opATAN,

// conversion
opTOINT,
opTOREAL,
opTOSTRING,

// measuring
opLENGTH,
opAREA,

@@ -50,7 +54,10 @@ class QgsSearchTreeNode
opGE, // >=
opLE, // <=
opRegexp, // ~
opLike // LIKE
opLike, // LIKE

// string handling
opCONCAT
};

//! constructors
@@ -92,6 +92,8 @@ string "'"{str_char}*"'"
"to real" { yylval.op = QgsSearchTreeNode::opTOREAL; return FUNCTION;}
"to string" { yylval.op = QgsSearchTreeNode::opTOSTRING; return FUNCTION;}
"||" { return CONCAT; }
[+-/*^] { return yytext[0]; }
[()] { return yytext[0]; }
@@ -62,6 +62,7 @@ void addToTmpNodes(QgsSearchTreeNode* node);
%token <number> NUMBER
%token <op> COMPARISON
%token <op> FUNCTION
%token CONCAT
%token IS
%token AREA
%token LENGTH
@@ -95,6 +96,8 @@ void addToTmpNodes(QgsSearchTreeNode* node);

%left COMPARISON

%left CONCAT

%left '+' '-'
%left '*' '/'
%left '^'
@@ -136,6 +139,7 @@ scalar_exp:
| '(' scalar_exp ')' { $$ = $2; }
| '+' scalar_exp %prec UMINUS { $$ = $2; }
| '-' scalar_exp %prec UMINUS { $$ = $2; if ($$->type() == QgsSearchTreeNode::tNumber) $$->setNumber(- $$->number()); }
| scalar_exp CONCAT scalar_exp { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opCONCAT, $1, $3); joinTmpNodes($$, $1, $3); }
| AREA { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opAREA, 0, 0); addToTmpNodes($$); }
| LENGTH { $$ = new QgsSearchTreeNode(QgsSearchTreeNode::opLENGTH, 0, 0); addToTmpNodes($$); }
| NUMBER { $$ = new QgsSearchTreeNode($1); addToTmpNodes($$); }
@@ -214,6 +214,9 @@ QString QgsSearchTreeNode::makeSearchString()
case opRegexp: str += " ~ "; break;
case opLike: str += " LIKE "; break;

// TODO: other opeators / functions
case opCONCAT: str += " || "; break;

default: str += " ? ";
}

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

// string concatenation ||
if ( mLeft && mRight && mOp == opCONCAT )
{
if ( value1.isNumeric() && value2.isNumeric() )
{
return QgsSearchTreeValue( 5, "Operator doesn't match the argument types." );
}
else
{
QString arg1 = value1.isNumeric() ? QString::number( value1.number() ) : value1.string();
QString arg2 = value2.isNumeric() ? QString::number( value2.number() ) : value2.string();
return QgsSearchTreeValue( arg1 + arg2 );
}
}

// for other operators, convert strings to numbers if needed
double val1, val2;
if ( value1.isNumeric() )
@@ -72,9 +72,13 @@ class CORE_EXPORT QgsSearchTreeNode
opASIN,
opACOS,
opATAN,

// conversion
opTOINT,
opTOREAL,
opTOSTRING,

// measuring
opLENGTH,
opAREA,

@@ -88,7 +92,10 @@ class CORE_EXPORT QgsSearchTreeNode
opGE, // >=
opLE, // <=
opRegexp, // ~
opLike // LIKE
opLike, // LIKE

// string handling
opCONCAT
};

//! constructors

0 comments on commit 9da341a

Please sign in to comment.