Skip to content

Commit 3599700

Browse files
committed
[FEATURE] implement coalesce and concat function expressions (implements #4551)
1 parent 86e9129 commit 3599700

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

src/core/qgsexpression.cpp

+24-3
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ static QVariant fcnToString( const QVariantList& values, QgsFeature* , QgsExpres
270270
{
271271
return QVariant( getStringValue( values.at( 0 ), parent ) );
272272
}
273+
static QVariant fcnCoalesce( const QVariantList& values, QgsFeature* , QgsExpression* )
274+
{
275+
foreach( const QVariant &value, values )
276+
{
277+
if ( value.isNull() )
278+
continue;
279+
return value;
280+
}
281+
return QVariant();
282+
}
273283
static QVariant fcnLower( const QVariantList& values, QgsFeature* , QgsExpression* parent )
274284
{
275285
QString str = getStringValue( values.at( 0 ), parent );
@@ -324,6 +334,15 @@ static QVariant fcnFeatureId( const QVariantList& , QgsFeature* f, QgsExpression
324334
// TODO: handling of 64-bit feature ids?
325335
return f ? QVariant(( int )f->id() ) : QVariant();
326336
}
337+
static QVariant fcnConcat( const QVariantList& values, QgsFeature* , QgsExpression *parent )
338+
{
339+
QString concat;
340+
foreach( const QVariant &value, values )
341+
{
342+
concat += getStringValue( value, parent );
343+
}
344+
return concat;
345+
}
327346

328347
#define ENSURE_GEOM_TYPE(f, g, geomtype) if (!f) return QVariant(); \
329348
QgsGeometry* g = f->geometry(); \
@@ -431,13 +450,15 @@ const QList<QgsExpression::FunctionDef> &QgsExpression::BuiltinFunctions()
431450
<< FunctionDef( "toint", 1, fcnToInt, QObject::tr( "Conversions" ) )
432451
<< FunctionDef( "toreal", 1, fcnToReal, QObject::tr( "Conversions" ) )
433452
<< FunctionDef( "tostring", 1, fcnToString, QObject::tr( "Conversions" ) )
453+
<< FunctionDef( "coalesce", -1, fcnCoalesce, QObject::tr( "Conversions" ) )
434454
// string manipulation
435455
<< FunctionDef( "lower", 1, fcnLower, QObject::tr( "String" ) )
436456
<< FunctionDef( "upper", 1, fcnUpper, QObject::tr( "String" ) )
437457
<< FunctionDef( "length", 1, fcnLength, QObject::tr( "String" ) )
438458
<< FunctionDef( "replace", 3, fcnReplace, QObject::tr( "String" ) )
439459
<< FunctionDef( "regexp_replace", 3, fcnRegexpReplace, QObject::tr( "String" ) )
440460
<< FunctionDef( "substr", 3, fcnSubstr, QObject::tr( "String" ) )
461+
<< FunctionDef( "concat", -1, fcnConcat, QObject::tr( "String" ) )
441462
// geometry accessors
442463
<< FunctionDef( "xat", 1, fcnXat, QObject::tr( "Geometry" ), "", true )
443464
<< FunctionDef( "yat", 1, fcnYat, QObject::tr( "Geometry" ), "", true )
@@ -693,7 +714,7 @@ QgsExpression::Node* QgsExpression::Node::createFromOgcFilter( QDomElement &elem
693714
QgsExpression::Node *operand2 = 0, *upperBound = 0;
694715

695716
QDomElement operandElem = element.firstChildElement();
696-
while( !operandElem.isNull() )
717+
while ( !operandElem.isNull() )
697718
{
698719
if ( operandElem.localName() == "LowerBoundary" )
699720
{
@@ -1340,8 +1361,8 @@ QVariant QgsExpression::NodeFunction::eval( QgsExpression* parent, QgsFeature* f
13401361
{
13411362
QVariant v = n->eval( parent, f );
13421363
ENSURE_NO_EVAL_ERROR;
1343-
if ( isNull( v ) )
1344-
return QVariant(); // all "normal" functions return NULL when any parameter is NULL
1364+
if ( isNull( v ) && fd.mFcn != fcnCoalesce )
1365+
return QVariant(); // all "normal" functions return NULL, when any parameter is NULL (so coalesce is abnormal)
13451366
argValues.append( v );
13461367
}
13471368
}

src/core/qgsexpressionparser.yy

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ expression:
165165
exp_error("Function is not known");
166166
YYERROR;
167167
}
168-
if (QgsExpression::BuiltinFunctions()[fnIndex].mParams != $3->count())
168+
if ( QgsExpression::BuiltinFunctions()[fnIndex].mParams != -1 && QgsExpression::BuiltinFunctions()[fnIndex].mParams != $3->count() )
169169
{
170170
exp_error("Function is called with wrong number of arguments");
171171
YYERROR;

0 commit comments

Comments
 (0)