Skip to content

Commit

Permalink
Support string concatenation using the standard sql concatenation ope…
Browse files Browse the repository at this point in the history
…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@13940 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Jul 20, 2010
1 parent e0afaaa commit a2a985b
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 2 deletions.
9 changes: 8 additions & 1 deletion python/core/qgssearchtreenode.sip
Expand Up @@ -36,9 +36,13 @@ class QgsSearchTreeNode
opASIN,
opACOS,
opATAN,

// conversion
opTOINT,
opTOREAL,
opTOSTRING,

// measuring
opLENGTH,
opAREA,

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

// string handling
opCONCAT
};

//! constructors
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgssearchstringlexer.ll
Expand Up @@ -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]; }
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgssearchstringparser.yy
Expand Up @@ -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
Expand Down Expand Up @@ -95,6 +96,8 @@ void addToTmpNodes(QgsSearchTreeNode* node);

%left COMPARISON

%left CONCAT

%left '+' '-'
%left '*' '/'
%left '^'
Expand Down Expand Up @@ -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($$); }
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgssearchtreenode.cpp
Expand Up @@ -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 += " ? ";
}

Expand Down Expand Up @@ -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() )
Expand Down
9 changes: 8 additions & 1 deletion src/core/qgssearchtreenode.h
Expand Up @@ -72,9 +72,13 @@ class CORE_EXPORT QgsSearchTreeNode
opASIN,
opACOS,
opATAN,

// conversion
opTOINT,
opTOREAL,
opTOSTRING,

// measuring
opLENGTH,
opAREA,

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

// string handling
opCONCAT
};

//! constructors
Expand Down

0 comments on commit a2a985b

Please sign in to comment.