Allow expression functions to include 0 length parameter lists

This change allows for some cleanups to the built in expression
functions, by making it possible to differentiate variables
(eg $feature) from functions which don't require parameters
(eg uuid(), now()... ). Also adds aliases for uuid(), now(), and
pi().
This commit is contained in:
Nyall Dawson 2015-05-03 20:56:19 +10:00
parent bd9e02be95
commit 96db1bdb7e
7 changed files with 25 additions and 39 deletions

View File

@ -1,12 +0,0 @@
<h3>$now function</h3>
Returns the current date and time
<h4>Syntax</h4>
<pre>$now</pre>
<h4>Arguments</h4>
None
<h4>Example</h4>
<pre>$now &rarr; 2012-07-22T13:24:57</pre>

View File

@ -1,11 +0,0 @@
<h3>$pi constant</h3>
Returns pi as value for calculations
<h4>Syntax</h4>
<pre>$pi</pre>
<h4>Arguments</h4>
None
<h4>Example</h4>
<pre>$pi &rarr; 3.14159265358979</pre>

View File

@ -1,13 +0,0 @@
<h3>$uuid function</h3>
Generates a Universally Unique Identifier (UUID) for each row using the Qt
<a href='http://qt-project.org/doc/qt-4.8/quuid.html#createUuid'>QUuid::createUuid</a>
method. Each UUID is 38 characters long.
<h4>Syntax</h4>
<pre>$uuid</pre>
<h4>Arguments</h4>
None
<h4>Example</h4>
<pre>$uuid &rarr; {0bd2f60f-f157-4a6d-96af-d4ba4cb366a1}</pre>

View File

@ -1728,7 +1728,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "scale_exp", 6, fcnExpScale, "Math" )
<< new StaticFunction( "floor", 1, fcnFloor, "Math" )
<< new StaticFunction( "ceil", 1, fcnCeil, "Math" )
<< new StaticFunction( "$pi", 0, fcnPi, "Math" )
<< new StaticFunction( "pi", 0, fcnPi, "Math", QString(), false, QStringList(), false, QStringList() << "$pi" )
<< new StaticFunction( "to_int", 1, fcnToInt, "Conversions", QString(), false, QStringList(), false, QStringList() << "toint" )
<< new StaticFunction( "to_real", 1, fcnToReal, "Conversions", QString(), false, QStringList(), false, QStringList() << "toreal" )
<< new StaticFunction( "to_string", 1, fcnToString, "Conversions", QString(), false, QStringList(), false, QStringList() << "tostring" )
@ -1739,7 +1739,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "coalesce", -1, fcnCoalesce, "Conditionals" )
<< new StaticFunction( "if", 3, fcnIf, "Conditionals", "", False, QStringList(), true )
<< new StaticFunction( "regexp_match", 2, fcnRegexpMatch, "Conditionals" )
<< new StaticFunction( "$now", 0, fcnNow, "Date and Time" )
<< new StaticFunction( "now", 0, fcnNow, "Date and Time", QString(), false, QStringList(), false, QStringList() << "$now" )
<< new StaticFunction( "age", 2, fcnAge, "Date and Time" )
<< new StaticFunction( "year", 1, fcnYear, "Date and Time" )
<< new StaticFunction( "month", 1, fcnMonth, "Date and Time" )
@ -1817,7 +1817,7 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
<< new StaticFunction( "$scale", 0, fcnScale, "Record" )
<< new StaticFunction( "$uuid", 0, fcnUuid, "Record" )
<< new StaticFunction( "uuid", 0, fcnUuid, "Record", QString(), false, QStringList(), false, QStringList() << "$uuid" )
<< new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QStringList(), false, QStringList() << "getFeature" )
//return all attributes string for referencedColumns - this is caught by

View File

@ -196,6 +196,25 @@ expression:
delete $1;
}
| FUNCTION '(' ')'
{
int fnIndex = QgsExpression::functionIndex(*$1);
if (fnIndex == -1)
{
// this should not actually happen because already in lexer we check whether an identifier is a known function
// (if the name is not known the token is parsed as a column)
exp_error(parser_ctx, "Function is not known");
YYERROR;
}
if ( QgsExpression::Functions()[fnIndex]->params() != 0 )
{
exp_error(parser_ctx, "Function is called with wrong number of arguments");
YYERROR;
}
$$ = new QgsExpression::NodeFunction(fnIndex, new QgsExpression::NodeList());
delete $1;
}
| expression IN '(' exp_list ')' { $$ = new QgsExpression::NodeInOperator($1, $4, false); }
| expression NOT IN '(' exp_list ')' { $$ = new QgsExpression::NodeInOperator($1, $5, true); }

View File

@ -408,6 +408,8 @@ void QgsExpressionBuilderWidget::updateFunctionTree()
continue;
if ( func->params() != 0 )
name += "(";
else if ( !name.startsWith( "$" ) )
name += "()";
registerItem( func->group(), func->name(), " " + name + " ", func->helptext() );
}

View File

@ -297,6 +297,7 @@ class TestQgsExpression: public QObject
QTest::newRow( "concat numbers" ) << "1 || 2" << false << QVariant( "12" );
// math functions
QTest::newRow( "pi" ) << "pi()" << false << QVariant( M_PI );
QTest::newRow( "sqrt" ) << "sqrt(16)" << false << QVariant( 4. );
QTest::newRow( "abs(0.1)" ) << "abs(0.1)" << false << QVariant( 0.1 );
QTest::newRow( "abs(0)" ) << "abs(0)" << false << QVariant( 0. );