Skip to content

Commit b4f8614

Browse files
committed
Add referencedFunctions() to expressions
1 parent edb12b4 commit b4f8614

10 files changed

Lines changed: 136 additions & 0 deletions

File tree

‎python/core/auto_generated/expression/qgsexpression.sip.in‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ If the list contains a NULL QString, there is a variable name used
176176
which is determined at runtime.
177177

178178
.. versionadded:: 3.0
179+
%End
180+
181+
QSet<QString> referencedFunctions() const;
182+
%Docstring
183+
Return a list of all functions which are used in this expression.
184+
185+
.. versionadded:: 3.2
179186
%End
180187

181188
QSet<int> referencedAttributeIndexes( const QgsFields &fields ) const;

‎python/core/auto_generated/expression/qgsexpressionnode.sip.in‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ to evaluate child nodes.
196196
virtual QSet<QString> referencedVariables() const = 0;
197197
%Docstring
198198
Return a set of all variables which are used in this expression.
199+
%End
200+
201+
virtual QSet<QString> referencedFunctions() const = 0;
202+
%Docstring
203+
Return a set of all functions which are used in this expression.
199204
%End
200205

201206
virtual bool needsGeometry() const = 0;

‎python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Returns the node the operator will operate upon.
5555

5656
virtual QSet<QString> referencedVariables() const;
5757

58+
virtual QSet<QString> referencedFunctions() const;
59+
5860
virtual bool needsGeometry() const;
5961

6062
virtual QgsExpressionNode *clone() const /Factory/;
@@ -154,6 +156,9 @@ Returns the node to the right of the operator.
154156

155157
virtual QSet<QString> referencedVariables() const;
156158

159+
virtual QSet<QString> referencedFunctions() const;
160+
161+
157162
virtual bool needsGeometry() const;
158163

159164
virtual QgsExpressionNode *clone() const /Factory/;
@@ -224,6 +229,8 @@ Returns the list of nodes to search for matching values within.
224229

225230
virtual QSet<QString> referencedVariables() const;
226231

232+
virtual QSet<QString> referencedFunctions() const;
233+
227234
virtual bool needsGeometry() const;
228235

229236
virtual QgsExpressionNode *clone() const /Factory/;
@@ -275,6 +282,8 @@ Returns a list of arguments specified for the function.
275282

276283
virtual QSet<QString> referencedVariables() const;
277284

285+
virtual QSet<QString> referencedFunctions() const;
286+
278287
virtual bool needsGeometry() const;
279288

280289
virtual QgsExpressionNode *clone() const /Factory/;
@@ -323,6 +332,8 @@ The value of the literal.
323332

324333
virtual QSet<QString> referencedVariables() const;
325334

335+
virtual QSet<QString> referencedFunctions() const;
336+
326337
virtual bool needsGeometry() const;
327338

328339
virtual QgsExpressionNode *clone() const /Factory/;
@@ -367,6 +378,8 @@ The name of the column.
367378

368379
virtual QSet<QString> referencedVariables() const;
369380

381+
virtual QSet<QString> referencedFunctions() const;
382+
370383
virtual bool needsGeometry() const;
371384

372385

@@ -466,6 +479,8 @@ The ELSE expression used for the condition.
466479

467480
virtual QSet<QString> referencedVariables() const;
468481

482+
virtual QSet<QString> referencedFunctions() const;
483+
469484
virtual bool needsGeometry() const;
470485

471486
virtual QgsExpressionNode *clone() const /Factory/;

‎src/core/expression/qgsexpression.cpp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,14 @@ QSet<QString> QgsExpression::referencedVariables() const
276276
return d->mRootNode->referencedVariables();
277277
}
278278

279+
QSet<QString> QgsExpression::referencedFunctions() const
280+
{
281+
if ( !d->mRootNode )
282+
return QSet<QString>();
283+
284+
return d->mRootNode->referencedFunctions();
285+
}
286+
279287
QSet<int> QgsExpression::referencedAttributeIndexes( const QgsFields &fields ) const
280288
{
281289
if ( !d->mRootNode )

‎src/core/expression/qgsexpression.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,13 @@ class CORE_EXPORT QgsExpression
258258
*/
259259
QSet<QString> referencedVariables() const;
260260

261+
/**
262+
* Return a list of all functions which are used in this expression.
263+
*
264+
* \since QGIS 3.2
265+
*/
266+
QSet<QString> referencedFunctions() const;
267+
261268
/**
262269
* Return a list of field name indexes obtained from the provided fields.
263270
*

‎src/core/expression/qgsexpressionnode.cpp‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,4 @@ void QgsExpressionNode::cloneTo( QgsExpressionNode *target ) const
5757
target->parserFirstColumn = parserFirstColumn;
5858
target->parserFirstLine = parserFirstLine;
5959
}
60+

‎src/core/expression/qgsexpressionnode.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,11 @@ class CORE_EXPORT QgsExpressionNode SIP_ABSTRACT
222222
*/
223223
virtual QSet<QString> referencedVariables() const = 0;
224224

225+
/**
226+
* Return a set of all functions which are used in this expression.
227+
*/
228+
virtual QSet<QString> referencedFunctions() const = 0;
229+
225230
/**
226231
* Abstract virtual method which returns if the geometry is required to evaluate
227232
* this expression.

‎src/core/expression/qgsexpressionnodeimpl.cpp‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ QSet<QString> QgsExpressionNodeUnaryOperator::referencedVariables() const
137137
return mOperand->referencedVariables();
138138
}
139139

140+
QSet<QString> QgsExpressionNodeUnaryOperator::referencedFunctions() const
141+
{
142+
return mOperand->referencedFunctions();
143+
}
144+
140145
bool QgsExpressionNodeUnaryOperator::needsGeometry() const
141146
{
142147
return mOperand->needsGeometry();
@@ -720,6 +725,11 @@ QSet<QString> QgsExpressionNodeBinaryOperator::referencedVariables() const
720725
return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
721726
}
722727

728+
QSet<QString> QgsExpressionNodeBinaryOperator::referencedFunctions() const
729+
{
730+
return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
731+
}
732+
723733
bool QgsExpressionNodeBinaryOperator::needsGeometry() const
724734
{
725735
return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
@@ -978,6 +988,23 @@ QSet<QString> QgsExpressionNodeFunction::referencedVariables() const
978988
}
979989
}
980990

991+
QSet<QString> QgsExpressionNodeFunction::referencedFunctions() const
992+
{
993+
QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
994+
QSet<QString> functions = QSet<QString>();
995+
functions.insert( fd->name() );
996+
997+
if ( !mArgs )
998+
return functions;
999+
1000+
const QList< QgsExpressionNode * > nodeList = mArgs->list();
1001+
for ( QgsExpressionNode *n : nodeList )
1002+
{
1003+
functions.unite( n->referencedFunctions() );
1004+
}
1005+
return functions;
1006+
}
1007+
9811008
bool QgsExpressionNodeFunction::needsGeometry() const
9821009
{
9831010
bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry( this );
@@ -1128,6 +1155,11 @@ QSet<QString> QgsExpressionNodeLiteral::referencedVariables() const
11281155
return QSet<QString>();
11291156
}
11301157

1158+
QSet<QString> QgsExpressionNodeLiteral::referencedFunctions() const
1159+
{
1160+
return QSet<QString>();
1161+
}
1162+
11311163
bool QgsExpressionNodeLiteral::needsGeometry() const
11321164
{
11331165
return false;
@@ -1215,6 +1247,11 @@ QSet<QString> QgsExpressionNodeColumnRef::referencedVariables() const
12151247
return QSet<QString>();
12161248
}
12171249

1250+
QSet<QString> QgsExpressionNodeColumnRef::referencedFunctions() const
1251+
{
1252+
return QSet<QString>();
1253+
}
1254+
12181255
bool QgsExpressionNodeColumnRef::needsGeometry() const
12191256
{
12201257
return false;
@@ -1338,6 +1375,20 @@ QSet<QString> QgsExpressionNodeCondition::referencedVariables() const
13381375
return lst;
13391376
}
13401377

1378+
QSet<QString> QgsExpressionNodeCondition::referencedFunctions() const
1379+
{
1380+
QSet<QString> lst;
1381+
for ( WhenThen *cond : mConditions )
1382+
{
1383+
lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1384+
}
1385+
1386+
if ( mElseExp )
1387+
lst += mElseExp->referencedFunctions();
1388+
1389+
return lst;
1390+
}
1391+
13411392
bool QgsExpressionNodeCondition::needsGeometry() const
13421393
{
13431394
for ( WhenThen *cond : mConditions )
@@ -1393,6 +1444,16 @@ QSet<QString> QgsExpressionNodeInOperator::referencedVariables() const
13931444
return lst;
13941445
}
13951446

1447+
QSet<QString> QgsExpressionNodeInOperator::referencedFunctions() const
1448+
{
1449+
QSet<QString> lst( mNode->referencedFunctions() );
1450+
const QList< QgsExpressionNode * > nodeList = mList->list();
1451+
for ( const QgsExpressionNode *n : nodeList )
1452+
lst.unite( n->referencedFunctions() );
1453+
return lst;
1454+
1455+
}
1456+
13961457
QgsExpressionNodeCondition::WhenThen::WhenThen( QgsExpressionNode *whenExp, QgsExpressionNode *thenExp )
13971458
: mWhenExp( whenExp )
13981459
, mThenExp( thenExp )
@@ -1414,3 +1475,4 @@ QString QgsExpressionNodeBinaryOperator::text() const
14141475
{
14151476
return BINARY_OPERATOR_TEXT[mOp];
14161477
}
1478+

‎src/core/expression/qgsexpressionnodeimpl.h‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class CORE_EXPORT QgsExpressionNodeUnaryOperator : public QgsExpressionNode
6464

6565
QSet<QString> referencedColumns() const override;
6666
QSet<QString> referencedVariables() const override;
67+
QSet<QString> referencedFunctions() const override;
6768
bool needsGeometry() const override;
6869
QgsExpressionNode *clone() const override SIP_FACTORY;
6970

@@ -162,6 +163,8 @@ class CORE_EXPORT QgsExpressionNodeBinaryOperator : public QgsExpressionNode
162163

163164
QSet<QString> referencedColumns() const override;
164165
QSet<QString> referencedVariables() const override;
166+
QSet<QString> referencedFunctions() const override;
167+
165168
bool needsGeometry() const override;
166169
QgsExpressionNode *clone() const override SIP_FACTORY;
167170
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
@@ -241,6 +244,7 @@ class CORE_EXPORT QgsExpressionNodeInOperator : public QgsExpressionNode
241244

242245
QSet<QString> referencedColumns() const override;
243246
QSet<QString> referencedVariables() const override;
247+
QSet<QString> referencedFunctions() const override;
244248
bool needsGeometry() const override;
245249
QgsExpressionNode *clone() const override SIP_FACTORY;
246250
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
@@ -284,6 +288,7 @@ class CORE_EXPORT QgsExpressionNodeFunction : public QgsExpressionNode
284288

285289
QSet<QString> referencedColumns() const override;
286290
QSet<QString> referencedVariables() const override;
291+
QSet<QString> referencedFunctions() const override;
287292
bool needsGeometry() const override;
288293
QgsExpressionNode *clone() const override SIP_FACTORY;
289294
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
@@ -321,6 +326,7 @@ class CORE_EXPORT QgsExpressionNodeLiteral : public QgsExpressionNode
321326

322327
QSet<QString> referencedColumns() const override;
323328
QSet<QString> referencedVariables() const override;
329+
QSet<QString> referencedFunctions() const override;
324330
bool needsGeometry() const override;
325331
QgsExpressionNode *clone() const override SIP_FACTORY;
326332
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
@@ -356,6 +362,7 @@ class CORE_EXPORT QgsExpressionNodeColumnRef : public QgsExpressionNode
356362

357363
QSet<QString> referencedColumns() const override;
358364
QSet<QString> referencedVariables() const override;
365+
QSet<QString> referencedFunctions() const override;
359366
bool needsGeometry() const override;
360367

361368
QgsExpressionNode *clone() const override SIP_FACTORY;
@@ -456,6 +463,7 @@ class CORE_EXPORT QgsExpressionNodeCondition : public QgsExpressionNode
456463

457464
QSet<QString> referencedColumns() const override;
458465
QSet<QString> referencedVariables() const override;
466+
QSet<QString> referencedFunctions() const override;
459467
bool needsGeometry() const override;
460468
QgsExpressionNode *clone() const override SIP_FACTORY;
461469
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;

‎tests/src/core/testqgsexpression.cpp‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,24 @@ class TestQgsExpression: public QObject
18611861
QCOMPARE( refVar, expectedVars );
18621862
}
18631863

1864+
1865+
void referenced_functions()
1866+
{
1867+
QSet<QString> expectedFunctions;
1868+
expectedFunctions << QStringLiteral( "current_value" )
1869+
<< QStringLiteral( "var" )
1870+
<< QStringLiteral( "intersects" )
1871+
<< QStringLiteral( "$geometry" )
1872+
<< QStringLiteral( "buffer" );
1873+
1874+
QgsExpression exp( QStringLiteral( "current_value( 'FIELD_NAME' ) = \"A_VALUE\" AND intersects(buffer($geometry, 10), @current_geometry)" ) );
1875+
QCOMPARE( exp.hasParserError(), false );
1876+
QSet<QString> refVar = exp.referencedFunctions();
1877+
1878+
QCOMPARE( refVar, expectedFunctions );
1879+
}
1880+
1881+
18641882
void referenced_columns_all_attributes()
18651883
{
18661884
QgsExpression exp( QStringLiteral( "attribute($currentfeature,'test')" ) );

0 commit comments

Comments
 (0)