Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add referencedFunctions() to expressions
  • Loading branch information
elpaso committed May 15, 2018
1 parent edb12b4 commit b4f8614
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 0 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_generated/expression/qgsexpression.sip.in
Expand Up @@ -176,6 +176,13 @@ If the list contains a NULL QString, there is a variable name used
which is determined at runtime.

.. versionadded:: 3.0
%End

QSet<QString> referencedFunctions() const;
%Docstring
Return a list of all functions which are used in this expression.

.. versionadded:: 3.2
%End

QSet<int> referencedAttributeIndexes( const QgsFields &fields ) const;
Expand Down
Expand Up @@ -196,6 +196,11 @@ to evaluate child nodes.
virtual QSet<QString> referencedVariables() const = 0;
%Docstring
Return a set of all variables which are used in this expression.
%End

virtual QSet<QString> referencedFunctions() const = 0;
%Docstring
Return a set of all functions which are used in this expression.
%End

virtual bool needsGeometry() const = 0;
Expand Down
15 changes: 15 additions & 0 deletions python/core/auto_generated/expression/qgsexpressionnodeimpl.sip.in
Expand Up @@ -55,6 +55,8 @@ Returns the node the operator will operate upon.

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;

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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;


virtual bool needsGeometry() const;

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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;

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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;

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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;

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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;


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

virtual QSet<QString> referencedVariables() const;

virtual QSet<QString> referencedFunctions() const;

virtual bool needsGeometry() const;

virtual QgsExpressionNode *clone() const /Factory/;
Expand Down
8 changes: 8 additions & 0 deletions src/core/expression/qgsexpression.cpp
Expand Up @@ -276,6 +276,14 @@ QSet<QString> QgsExpression::referencedVariables() const
return d->mRootNode->referencedVariables();
}

QSet<QString> QgsExpression::referencedFunctions() const
{
if ( !d->mRootNode )
return QSet<QString>();

return d->mRootNode->referencedFunctions();
}

QSet<int> QgsExpression::referencedAttributeIndexes( const QgsFields &fields ) const
{
if ( !d->mRootNode )
Expand Down
7 changes: 7 additions & 0 deletions src/core/expression/qgsexpression.h
Expand Up @@ -258,6 +258,13 @@ class CORE_EXPORT QgsExpression
*/
QSet<QString> referencedVariables() const;

/**
* Return a list of all functions which are used in this expression.
*
* \since QGIS 3.2
*/
QSet<QString> referencedFunctions() const;

/**
* Return a list of field name indexes obtained from the provided fields.
*
Expand Down
1 change: 1 addition & 0 deletions src/core/expression/qgsexpressionnode.cpp
Expand Up @@ -57,3 +57,4 @@ void QgsExpressionNode::cloneTo( QgsExpressionNode *target ) const
target->parserFirstColumn = parserFirstColumn;
target->parserFirstLine = parserFirstLine;
}

5 changes: 5 additions & 0 deletions src/core/expression/qgsexpressionnode.h
Expand Up @@ -222,6 +222,11 @@ class CORE_EXPORT QgsExpressionNode SIP_ABSTRACT
*/
virtual QSet<QString> referencedVariables() const = 0;

/**
* Return a set of all functions which are used in this expression.
*/
virtual QSet<QString> referencedFunctions() const = 0;

/**
* Abstract virtual method which returns if the geometry is required to evaluate
* this expression.
Expand Down
62 changes: 62 additions & 0 deletions src/core/expression/qgsexpressionnodeimpl.cpp
Expand Up @@ -137,6 +137,11 @@ QSet<QString> QgsExpressionNodeUnaryOperator::referencedVariables() const
return mOperand->referencedVariables();
}

QSet<QString> QgsExpressionNodeUnaryOperator::referencedFunctions() const
{
return mOperand->referencedFunctions();
}

bool QgsExpressionNodeUnaryOperator::needsGeometry() const
{
return mOperand->needsGeometry();
Expand Down Expand Up @@ -720,6 +725,11 @@ QSet<QString> QgsExpressionNodeBinaryOperator::referencedVariables() const
return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
}

QSet<QString> QgsExpressionNodeBinaryOperator::referencedFunctions() const
{
return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
}

bool QgsExpressionNodeBinaryOperator::needsGeometry() const
{
return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
Expand Down Expand Up @@ -978,6 +988,23 @@ QSet<QString> QgsExpressionNodeFunction::referencedVariables() const
}
}

QSet<QString> QgsExpressionNodeFunction::referencedFunctions() const
{
QgsExpressionFunction *fd = QgsExpression::QgsExpression::Functions()[mFnIndex];
QSet<QString> functions = QSet<QString>();
functions.insert( fd->name() );

if ( !mArgs )
return functions;

const QList< QgsExpressionNode * > nodeList = mArgs->list();
for ( QgsExpressionNode *n : nodeList )
{
functions.unite( n->referencedFunctions() );
}
return functions;
}

bool QgsExpressionNodeFunction::needsGeometry() const
{
bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry( this );
Expand Down Expand Up @@ -1128,6 +1155,11 @@ QSet<QString> QgsExpressionNodeLiteral::referencedVariables() const
return QSet<QString>();
}

QSet<QString> QgsExpressionNodeLiteral::referencedFunctions() const
{
return QSet<QString>();
}

bool QgsExpressionNodeLiteral::needsGeometry() const
{
return false;
Expand Down Expand Up @@ -1215,6 +1247,11 @@ QSet<QString> QgsExpressionNodeColumnRef::referencedVariables() const
return QSet<QString>();
}

QSet<QString> QgsExpressionNodeColumnRef::referencedFunctions() const
{
return QSet<QString>();
}

bool QgsExpressionNodeColumnRef::needsGeometry() const
{
return false;
Expand Down Expand Up @@ -1338,6 +1375,20 @@ QSet<QString> QgsExpressionNodeCondition::referencedVariables() const
return lst;
}

QSet<QString> QgsExpressionNodeCondition::referencedFunctions() const
{
QSet<QString> lst;
for ( WhenThen *cond : mConditions )
{
lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
}

if ( mElseExp )
lst += mElseExp->referencedFunctions();

return lst;
}

bool QgsExpressionNodeCondition::needsGeometry() const
{
for ( WhenThen *cond : mConditions )
Expand Down Expand Up @@ -1393,6 +1444,16 @@ QSet<QString> QgsExpressionNodeInOperator::referencedVariables() const
return lst;
}

QSet<QString> QgsExpressionNodeInOperator::referencedFunctions() const
{
QSet<QString> lst( mNode->referencedFunctions() );
const QList< QgsExpressionNode * > nodeList = mList->list();
for ( const QgsExpressionNode *n : nodeList )
lst.unite( n->referencedFunctions() );
return lst;

}

QgsExpressionNodeCondition::WhenThen::WhenThen( QgsExpressionNode *whenExp, QgsExpressionNode *thenExp )
: mWhenExp( whenExp )
, mThenExp( thenExp )
Expand All @@ -1414,3 +1475,4 @@ QString QgsExpressionNodeBinaryOperator::text() const
{
return BINARY_OPERATOR_TEXT[mOp];
}

8 changes: 8 additions & 0 deletions src/core/expression/qgsexpressionnodeimpl.h
Expand Up @@ -64,6 +64,7 @@ class CORE_EXPORT QgsExpressionNodeUnaryOperator : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;

Expand Down Expand Up @@ -162,6 +163,8 @@ class CORE_EXPORT QgsExpressionNodeBinaryOperator : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;

bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
Expand Down Expand Up @@ -241,6 +244,7 @@ class CORE_EXPORT QgsExpressionNodeInOperator : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
Expand Down Expand Up @@ -284,6 +288,7 @@ class CORE_EXPORT QgsExpressionNodeFunction : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
Expand Down Expand Up @@ -321,6 +326,7 @@ class CORE_EXPORT QgsExpressionNodeLiteral : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
Expand Down Expand Up @@ -356,6 +362,7 @@ class CORE_EXPORT QgsExpressionNodeColumnRef : public QgsExpressionNode

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;

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

QSet<QString> referencedColumns() const override;
QSet<QString> referencedVariables() const override;
QSet<QString> referencedFunctions() const override;
bool needsGeometry() const override;
QgsExpressionNode *clone() const override SIP_FACTORY;
bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
Expand Down
18 changes: 18 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -1861,6 +1861,24 @@ class TestQgsExpression: public QObject
QCOMPARE( refVar, expectedVars );
}


void referenced_functions()
{
QSet<QString> expectedFunctions;
expectedFunctions << QStringLiteral( "current_value" )
<< QStringLiteral( "var" )
<< QStringLiteral( "intersects" )
<< QStringLiteral( "$geometry" )
<< QStringLiteral( "buffer" );

QgsExpression exp( QStringLiteral( "current_value( 'FIELD_NAME' ) = \"A_VALUE\" AND intersects(buffer($geometry, 10), @current_geometry)" ) );
QCOMPARE( exp.hasParserError(), false );
QSet<QString> refVar = exp.referencedFunctions();

QCOMPARE( refVar, expectedFunctions );
}


void referenced_columns_all_attributes()
{
QgsExpression exp( QStringLiteral( "attribute($currentfeature,'test')" ) );
Expand Down

0 comments on commit b4f8614

Please sign in to comment.