mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Modularize expressions
The file qgsexpressions.h has grown to one monolithic piece over the years. This makes it hard to maintain and slows down compilation because even small changes at one end will result in recompiling big parts of the source tree. It also requires the compiler to keep track of all these implementation details for said big parts of the source tree. This splits this implementation into smaller pieces. There are soe API changes connected to this, but since these can be considered implementation details, on which not many plugins rely, this shouldn't have a big impact on the ecosystem outside the source tree.
This commit is contained in:
parent
ac50214347
commit
ec40199862
@ -49,7 +49,6 @@
|
||||
%Include qgseditorwidgetsetup.sip
|
||||
%Include qgsellipsoidutils.sip
|
||||
%Include qgserror.sip
|
||||
%Include qgsexpression.sip
|
||||
%Include qgsexpressioncontext.sip
|
||||
%Include qgsexpressioncontextgenerator.sip
|
||||
%Include qgsfeature.sip
|
||||
@ -403,3 +402,8 @@
|
||||
%Include geometry/qgstriangle.sip
|
||||
%Include geometry/qgswkbtypes.sip
|
||||
%Include geometry/qgswkbptr.sip
|
||||
|
||||
%Include expression/qgsexpression.sip
|
||||
%Include expression/qgsexpressionnodeimpl.sip
|
||||
%Include expression/qgsexpressionnode.sip
|
||||
%Include expression/qgsexpressionfunction.sip
|
||||
|
514
python/core/expression/qgsexpression.sip
Normal file
514
python/core/expression/qgsexpression.sip
Normal file
@ -0,0 +1,514 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpression.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsExpression
|
||||
{
|
||||
%Docstring
|
||||
Class for parsing and evaluation of expressions (formerly called "search strings").
|
||||
The expressions try to follow both syntax and semantics of SQL expressions.
|
||||
|
||||
Usage:
|
||||
\code{.cpp}
|
||||
QgsExpression exp("gid*2 > 10 and type not in ('D','F'));
|
||||
if (exp.hasParserError())
|
||||
{
|
||||
// show error message with parserErrorString() and exit
|
||||
}
|
||||
QVariant result = exp.evaluate(feature, fields);
|
||||
if (exp.hasEvalError())
|
||||
{
|
||||
// show error message with evalErrorString()
|
||||
}
|
||||
else
|
||||
{
|
||||
// examine the result
|
||||
}
|
||||
\endcode
|
||||
|
||||
Three Value Logic
|
||||
=================
|
||||
|
||||
Similarly to SQL, this class supports three-value logic: true/false/unknown.
|
||||
Unknown value may be a result of operations with missing data (NULL). Please note
|
||||
that NULL is different value than zero or an empty string. For example
|
||||
3 > NULL returns unknown.
|
||||
|
||||
There is no special (three-value) 'boolean' type: true/false is represented as
|
||||
1/0 integer, unknown value is represented the same way as NULL values: NULL QVariant.
|
||||
|
||||
Performance
|
||||
===========
|
||||
|
||||
For better performance with many evaluations you may first call prepare(fields) function
|
||||
to find out indices of columns and then repeatedly call evaluate(feature).
|
||||
|
||||
Type conversion
|
||||
===============
|
||||
|
||||
Operators and functions that expect arguments to be of a particular
|
||||
type automatically convert the arguments to that type, e.g. sin('2.1') will convert
|
||||
the argument to a double, length(123) will first convert the number to a string.
|
||||
Explicit conversion can be achieved with to_int, to_real, to_string functions.
|
||||
If implicit or explicit conversion is invalid, the evaluation returns an error.
|
||||
Comparison operators do numeric comparison in case both operators are numeric (int/double)
|
||||
or they can be converted to numeric types.
|
||||
|
||||
Implicit sharing
|
||||
================
|
||||
|
||||
This class is implicitly shared, copying has a very low overhead.
|
||||
It is normally preferable to call `QgsExpression( otherExpression )` instead of
|
||||
`QgsExpression( otherExpression.expression() )`. A deep copy will only be made
|
||||
when prepare() is called. For usage this means mainly, that you should
|
||||
normally keep an unprepared master copy of a QgsExpression and whenever using it
|
||||
with a particular QgsFeatureIterator copy it just before and prepare it using the
|
||||
same context as the iterator.
|
||||
|
||||
Implicit sharing was added in 2.14
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpression.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsExpression( const QString &expr );
|
||||
%Docstring
|
||||
Creates a new expression based on the provided string.
|
||||
The string will immediately be parsed. For optimization
|
||||
prepare() should always be called before every
|
||||
loop in which this expression is used.
|
||||
%End
|
||||
|
||||
QgsExpression( const QgsExpression &other );
|
||||
%Docstring
|
||||
Create a copy of this expression. This is preferred
|
||||
over recreating an expression from a string since
|
||||
it does not need to be re-parsed.
|
||||
%End
|
||||
|
||||
|
||||
QgsExpression();
|
||||
%Docstring
|
||||
Create an empty expression.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
~QgsExpression();
|
||||
|
||||
bool operator==( const QgsExpression &other ) const;
|
||||
%Docstring
|
||||
Compares two expressions. The operator returns true
|
||||
if the expression string is equal.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool isValid() const;
|
||||
%Docstring
|
||||
Checks if this expression is valid.
|
||||
A valid expression could be parsed but does not necessarily evaluate properly.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool hasParserError() const;
|
||||
%Docstring
|
||||
Returns true if an error occurred when parsing the input expression
|
||||
:rtype: bool
|
||||
%End
|
||||
QString parserErrorString() const;
|
||||
%Docstring
|
||||
Returns parser error
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
const QgsExpressionNode *rootNode() const;
|
||||
%Docstring
|
||||
Returns root node of the expression. Root node is null is parsing has failed
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
|
||||
bool prepare( const QgsExpressionContext *context );
|
||||
%Docstring
|
||||
Get the expression ready for evaluation - find out column indexes.
|
||||
\param context context for preparing expression
|
||||
.. versionadded:: 2.12
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QSet<QString> referencedColumns() const;
|
||||
%Docstring
|
||||
Get list of columns referenced by the expression.
|
||||
|
||||
.. note::
|
||||
|
||||
If the returned list contains the QgsFeatureRequest.AllAttributes constant then
|
||||
all attributes from the layer are required for evaluation of the expression.
|
||||
QgsFeatureRequest.setSubsetOfAttributes automatically handles this case.
|
||||
|
||||
.. seealso:: referencedAttributeIndexes()
|
||||
:rtype: set of str
|
||||
%End
|
||||
|
||||
QSet<QString> referencedVariables() const;
|
||||
%Docstring
|
||||
Return a list of all variables which are used in this expression.
|
||||
If the list contains a NULL QString, there is a variable name used
|
||||
which is determined at runtime.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: set of str
|
||||
%End
|
||||
|
||||
QSet<int> referencedAttributeIndexes( const QgsFields &fields ) const;
|
||||
%Docstring
|
||||
Return a list of field name indexes obtained from the provided fields.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: set of int
|
||||
%End
|
||||
|
||||
bool needsGeometry() const;
|
||||
%Docstring
|
||||
Returns true if the expression uses feature geometry for some computation
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
||||
QVariant evaluate();
|
||||
%Docstring
|
||||
Evaluate the feature and return the result.
|
||||
.. note::
|
||||
|
||||
this method does not expect that prepare() has been called on this instance
|
||||
.. versionadded:: 2.12
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
QVariant evaluate( const QgsExpressionContext *context );
|
||||
%Docstring
|
||||
Evaluate the expression against the specified context and return the result.
|
||||
\param context context for evaluating expression
|
||||
.. note::
|
||||
|
||||
prepare() should be called before calling this method.
|
||||
.. versionadded:: 2.12
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool hasEvalError() const;
|
||||
%Docstring
|
||||
Returns true if an error occurred when evaluating last input
|
||||
:rtype: bool
|
||||
%End
|
||||
QString evalErrorString() const;
|
||||
%Docstring
|
||||
Returns evaluation error
|
||||
:rtype: str
|
||||
%End
|
||||
void setEvalErrorString( const QString &str );
|
||||
%Docstring
|
||||
Set evaluation error (used internally by evaluation functions)
|
||||
%End
|
||||
|
||||
bool isField() const;
|
||||
%Docstring
|
||||
Checks whether an expression consists only of a single field reference
|
||||
.. versionadded:: 2.9
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static bool checkExpression( const QString &text, const QgsExpressionContext *context, QString &errorMessage /Out/ );
|
||||
%Docstring
|
||||
Tests whether a string is a valid expression.
|
||||
\param text string to test
|
||||
\param context optional expression context
|
||||
\param errorMessage will be filled with any error message from the validation
|
||||
:return: true if string is a valid expression
|
||||
.. versionadded:: 2.12
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
void setExpression( const QString &expression );
|
||||
%Docstring
|
||||
Set the expression string, will reset the whole internal structure.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QString expression() const;
|
||||
%Docstring
|
||||
API calls, dump() will be used to create one instead.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QString dump() const;
|
||||
%Docstring
|
||||
expression() instead.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QgsDistanceArea *geomCalculator();
|
||||
%Docstring
|
||||
Return calculator used for distance and area calculations
|
||||
(used by $length, $area and $perimeter functions only)
|
||||
.. seealso:: setGeomCalculator()
|
||||
.. seealso:: distanceUnits()
|
||||
.. seealso:: areaUnits()
|
||||
:rtype: QgsDistanceArea
|
||||
%End
|
||||
|
||||
void setGeomCalculator( const QgsDistanceArea *calc );
|
||||
%Docstring
|
||||
Sets the geometry calculator used for distance and area calculations in expressions.
|
||||
(used by $length, $area and $perimeter functions only). By default, no geometry
|
||||
calculator is set and all distance and area calculations are performed using simple
|
||||
cartesian methods (ie no ellipsoidal calculations).
|
||||
\param calc geometry calculator. Ownership is not transferred. Set to a None to force
|
||||
cartesian calculations.
|
||||
.. seealso:: geomCalculator()
|
||||
%End
|
||||
|
||||
QgsUnitTypes::DistanceUnit distanceUnits() const;
|
||||
%Docstring
|
||||
Returns the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
|
||||
.. note::
|
||||
|
||||
distances are only converted when a geomCalculator() has been set
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: setDistanceUnits()
|
||||
.. seealso:: areaUnits()
|
||||
:rtype: QgsUnitTypes.DistanceUnit
|
||||
%End
|
||||
|
||||
void setDistanceUnits( QgsUnitTypes::DistanceUnit unit );
|
||||
%Docstring
|
||||
Sets the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
|
||||
.. note::
|
||||
|
||||
distances are only converted when a geomCalculator() has been set
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: distanceUnits()
|
||||
.. seealso:: setAreaUnits()
|
||||
%End
|
||||
|
||||
QgsUnitTypes::AreaUnit areaUnits() const;
|
||||
%Docstring
|
||||
Returns the desired areal units for calculations involving geomCalculator(), e.g., "$area".
|
||||
.. note::
|
||||
|
||||
areas are only converted when a geomCalculator() has been set
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: setAreaUnits()
|
||||
.. seealso:: distanceUnits()
|
||||
:rtype: QgsUnitTypes.AreaUnit
|
||||
%End
|
||||
|
||||
void setAreaUnits( QgsUnitTypes::AreaUnit unit );
|
||||
%Docstring
|
||||
Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
|
||||
.. note::
|
||||
|
||||
areas are only converted when a geomCalculator() has been set
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: areaUnits()
|
||||
.. seealso:: setDistanceUnits()
|
||||
%End
|
||||
|
||||
static QString replaceExpressionText( const QString &action, const QgsExpressionContext *context,
|
||||
const QgsDistanceArea *distanceArea = 0 );
|
||||
%Docstring
|
||||
This function replaces each expression between [% and %]
|
||||
in the string with the result of its evaluation with the specified context
|
||||
|
||||
Additional substitutions can be passed through the substitutionMap parameter
|
||||
\param action The source string in which placeholders should be replaced.
|
||||
\param context Expression context
|
||||
\param distanceArea Optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance
|
||||
and area conversion
|
||||
.. versionadded:: 2.12
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static double evaluateToDouble( const QString &text, const double fallbackValue );
|
||||
%Docstring
|
||||
Attempts to evaluate a text string as an expression to a resultant double
|
||||
value.
|
||||
\param text text to evaluate as expression
|
||||
\param fallbackValue value to return if text can not be evaluated as a double
|
||||
:return: evaluated double value, or fallback value
|
||||
.. versionadded:: 2.7
|
||||
.. note::
|
||||
|
||||
this method is inefficient for bulk evaluation of expressions, it is intended
|
||||
for one-off evaluations only.
|
||||
:rtype: float
|
||||
%End
|
||||
|
||||
enum SpatialOperator
|
||||
{
|
||||
soBbox,
|
||||
soIntersects,
|
||||
soContains,
|
||||
soCrosses,
|
||||
soEquals,
|
||||
soDisjoint,
|
||||
soOverlaps,
|
||||
soTouches,
|
||||
soWithin,
|
||||
};
|
||||
|
||||
static const QList<QgsExpressionFunction *> &Functions();
|
||||
%Docstring
|
||||
:rtype: list of QgsExpressionFunction
|
||||
%End
|
||||
|
||||
static const QStringList &BuiltinFunctions();
|
||||
%Docstring
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
static bool registerFunction( QgsExpressionFunction *function, bool transferOwnership = false );
|
||||
%Docstring
|
||||
Registers a function to the expression engine. This is required to allow expressions to utilize the function.
|
||||
\param function function to register
|
||||
\param transferOwnership set to true to transfer ownership of function to expression engine
|
||||
:return: true on successful registration
|
||||
.. seealso:: unregisterFunction
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static bool unregisterFunction( const QString &name );
|
||||
%Docstring
|
||||
Unregisters a function from the expression engine. The function will no longer be usable in expressions.
|
||||
\param name function name
|
||||
.. seealso:: registerFunction
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
||||
static void cleanRegisteredFunctions();
|
||||
%Docstring
|
||||
Deletes all registered functions whose ownership have been transferred to the expression engine.
|
||||
.. versionadded:: 2.12
|
||||
%End
|
||||
|
||||
static bool isFunctionName( const QString &name );
|
||||
%Docstring
|
||||
tells whether the identifier is a name of existing function
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
static int functionIndex( const QString &name );
|
||||
%Docstring
|
||||
return index of the function in Functions array
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
static int functionCount();
|
||||
%Docstring
|
||||
Returns the number of functions defined in the parser
|
||||
:return: The number of function defined in the parser.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
static QString quotedColumnRef( QString name );
|
||||
%Docstring
|
||||
Returns a quoted column reference (in double quotes)
|
||||
.. seealso:: quotedString()
|
||||
.. seealso:: quotedValue()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString quotedString( QString text );
|
||||
%Docstring
|
||||
Returns a quoted version of a string (in single quotes)
|
||||
.. seealso:: quotedValue()
|
||||
.. seealso:: quotedColumnRef()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString quotedValue( const QVariant &value );
|
||||
%Docstring
|
||||
Returns a string representation of a literal value, including appropriate
|
||||
quotations where required.
|
||||
\param value value to convert to a string representation
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: quotedString()
|
||||
.. seealso:: quotedColumnRef()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString quotedValue( const QVariant &value, QVariant::Type type );
|
||||
%Docstring
|
||||
Returns a string representation of a literal value, including appropriate
|
||||
quotations where required.
|
||||
\param value value to convert to a string representation
|
||||
\param type value type
|
||||
.. versionadded:: 2.14
|
||||
.. seealso:: quotedString()
|
||||
.. seealso:: quotedColumnRef()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
|
||||
static QString helpText( QString name );
|
||||
%Docstring
|
||||
Returns the help text for a specified function.
|
||||
\param name function name
|
||||
.. seealso:: variableHelpText()
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString variableHelpText( const QString &variableName, bool showValue = true, const QVariant &value = QVariant() );
|
||||
%Docstring
|
||||
Returns the help text for a specified variable.
|
||||
\param variableName name of variable
|
||||
\param showValue set to true to include current value of variable in help text
|
||||
\param value current value of variable to show in help text
|
||||
.. seealso:: helpText()
|
||||
.. versionadded:: 2.12
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString group( const QString &group );
|
||||
%Docstring
|
||||
Returns the translated name for a function group.
|
||||
\param group untranslated group name
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
static QString formatPreviewString( const QVariant &value );
|
||||
%Docstring
|
||||
Formats an expression result for friendly display to the user. Truncates the result to a sensible
|
||||
length, and presents text representations of non numeric/text types (e.g., geometries and features).
|
||||
\param value expression result to format
|
||||
:return: formatted string, may contain HTML formatting characters
|
||||
.. versionadded:: 2.14
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpression.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
286
python/core/expression/qgsexpressionfunction.sip
Normal file
286
python/core/expression/qgsexpressionfunction.sip
Normal file
@ -0,0 +1,286 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionfunction.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsExpressionFunction
|
||||
{
|
||||
%Docstring
|
||||
A abstract base class for defining QgsExpression functions.
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionfunction.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
|
||||
class Parameter
|
||||
{
|
||||
%Docstring
|
||||
Represents a single parameter passed to a function.
|
||||
.. versionadded:: 2.16
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionfunction.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
Parameter( const QString &name,
|
||||
bool optional = false,
|
||||
const QVariant &defaultValue = QVariant() );
|
||||
%Docstring
|
||||
Constructor for Parameter.
|
||||
\param name parameter name, used when named parameter are specified in an expression
|
||||
\param optional set to true if parameter should be optional
|
||||
\param defaultValue default value to use for optional parameters
|
||||
%End
|
||||
|
||||
QString name() const;
|
||||
%Docstring
|
||||
Returns the name of the parameter.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
bool optional() const;
|
||||
%Docstring
|
||||
Returns true if the parameter is optional.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QVariant defaultValue() const;
|
||||
%Docstring
|
||||
Returns the default value for the parameter.
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool operator==( const QgsExpressionFunction::Parameter &other ) const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
typedef QList< QgsExpressionFunction::Parameter > ParameterList;
|
||||
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
int params,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false );
|
||||
%Docstring
|
||||
Constructor for function which uses unnamed parameters
|
||||
%End
|
||||
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
int params,
|
||||
const QStringList &groups,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false );
|
||||
%Docstring
|
||||
Constructor for function which uses unnamed parameters and group list
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false );
|
||||
%Docstring
|
||||
Constructor for function which uses named parameter list.
|
||||
.. versionadded:: 2.16
|
||||
%End
|
||||
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QStringList &groups,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false );
|
||||
%Docstring
|
||||
Constructor for function which uses named parameter list and group list.
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
virtual ~QgsExpressionFunction();
|
||||
|
||||
QString name() const;
|
||||
%Docstring
|
||||
The name of the function.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
int params() const;
|
||||
%Docstring
|
||||
The number of parameters this function takes.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
int minParams() const;
|
||||
%Docstring
|
||||
The minimum number of parameters this function takes.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
const QgsExpressionFunction::ParameterList ¶meters() const;
|
||||
%Docstring
|
||||
Returns the list of named parameters for the function, if set.
|
||||
.. versionadded:: 2.16
|
||||
:rtype: QgsExpressionFunction.ParameterList
|
||||
%End
|
||||
|
||||
virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
|
||||
%Docstring
|
||||
Does this function use a geometry object.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual QStringList aliases() const;
|
||||
%Docstring
|
||||
Returns a list of possible aliases for the function. These include
|
||||
other permissible names for the function, e.g., deprecated names.
|
||||
:return: list of known aliases
|
||||
.. versionadded:: 2.9
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
bool lazyEval() const;
|
||||
%Docstring
|
||||
True if this function should use lazy evaluation. Lazy evaluation functions take QgsExpression.Node objects
|
||||
rather than the node results when called. You can use node->eval(parent, feature) to evaluate the node and return the result
|
||||
Functions are non lazy default and will be given the node return value when called.
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
%Docstring
|
||||
Will be called during prepare to determine if the function is static.
|
||||
A function is static if it will return the same value for every feature with different
|
||||
attributes and/or geometry.
|
||||
|
||||
By default this will return true, if all arguments that have been passed to the function
|
||||
are also static.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
%Docstring
|
||||
This will be called during the prepare step() of an expression if it is not static.
|
||||
|
||||
This can be used by functions to do any preparation steps that might help to speedup the upcoming
|
||||
evaluation.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
|
||||
%Docstring
|
||||
Returns a set of field names which are required for this function.
|
||||
May contain QgsFeatureRequest.AllAttributes to signal that all
|
||||
attributes are required.
|
||||
If in doubt this will return more fields than strictly required.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: set of str
|
||||
%End
|
||||
|
||||
bool isContextual() const;
|
||||
%Docstring
|
||||
Returns whether the function is only available if provided by a QgsExpressionContext object.
|
||||
.. versionadded:: 2.12
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool isDeprecated() const;
|
||||
%Docstring
|
||||
Returns true if the function is deprecated and should not be presented as a valid option
|
||||
to users in expression builders.
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QString group() const;
|
||||
%Docstring
|
||||
Returns the first group which the function belongs to.
|
||||
.. note::
|
||||
|
||||
consider using groups() instead, as some functions naturally belong in multiple groups
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QStringList groups() const;
|
||||
%Docstring
|
||||
Returns a list of the groups the function belongs to.
|
||||
.. versionadded:: 3.0
|
||||
.. seealso:: group()
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
const QString helpText() const;
|
||||
%Docstring
|
||||
The help text for the function.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) = 0;
|
||||
%Docstring
|
||||
Returns result of evaluating the function.
|
||||
\param values list of values passed to the function
|
||||
\param context context expression is being evaluated against
|
||||
\param parent parent expression
|
||||
:return: result of function
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
bool operator==( const QgsExpressionFunction &other ) const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool handlesNull() const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
|
||||
%Docstring
|
||||
This will return true if all the params for the provided function ``node`` are static within the
|
||||
constraints imposed by the ``context`` within the given ``parent``.
|
||||
|
||||
This can be used as callback for custom implementations of subclasses. It is the default for implementation
|
||||
for StaticFunction.isStatic.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionfunction.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
250
python/core/expression/qgsexpressionnode.sip
Normal file
250
python/core/expression/qgsexpressionnode.sip
Normal file
@ -0,0 +1,250 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionnode.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsExpressionNode /Abstract/
|
||||
{
|
||||
%Docstring
|
||||
|
||||
Abstract base class for all nodes that can appear in an expression.
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnode.h"
|
||||
%End
|
||||
|
||||
%ConvertToSubClassCode
|
||||
switch ( sipCpp->nodeType() )
|
||||
{
|
||||
case QgsExpressionNode::ntUnaryOperator:
|
||||
sipType = sipType_QgsExpressionNodeUnaryOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntBinaryOperator:
|
||||
sipType = sipType_QgsExpressionNodeBinaryOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntInOperator:
|
||||
sipType = sipType_QgsExpressionNodeInOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntFunction:
|
||||
sipType = sipType_QgsExpressionNodeFunction;
|
||||
break;
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
sipType = sipType_QgsExpressionNodeLiteral;
|
||||
break;
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
sipType = sipType_QgsExpressionNodeColumnRef;
|
||||
break;
|
||||
case QgsExpressionNode::ntCondition:
|
||||
sipType = sipType_QgsExpressionNodeCondition;
|
||||
break;
|
||||
default:
|
||||
sipType = 0;
|
||||
break;
|
||||
}
|
||||
%End
|
||||
public:
|
||||
enum NodeType
|
||||
{
|
||||
ntUnaryOperator,
|
||||
ntBinaryOperator,
|
||||
ntInOperator,
|
||||
ntFunction,
|
||||
ntLiteral,
|
||||
ntColumnRef,
|
||||
ntCondition
|
||||
};
|
||||
|
||||
|
||||
struct NamedNode
|
||||
{
|
||||
public:
|
||||
|
||||
NamedNode( const QString &name, QgsExpressionNode *node );
|
||||
%Docstring
|
||||
Constructor for NamedNode
|
||||
\param name node name
|
||||
\param node node
|
||||
%End
|
||||
|
||||
QString name;
|
||||
%Docstring
|
||||
Node name
|
||||
%End
|
||||
|
||||
QgsExpressionNode *node;
|
||||
%Docstring
|
||||
Node
|
||||
%End
|
||||
};
|
||||
|
||||
class NodeList
|
||||
{
|
||||
public:
|
||||
virtual ~NodeList();
|
||||
void append( QgsExpressionNode *node /Transfer/ );
|
||||
%Docstring
|
||||
Takes ownership of the provided node
|
||||
%End
|
||||
|
||||
void append( QgsExpressionNode::NamedNode *node /Transfer/ );
|
||||
%Docstring
|
||||
Adds a named node. Takes ownership of the provided node.
|
||||
.. versionadded:: 2.16
|
||||
%End
|
||||
|
||||
int count() const;
|
||||
%Docstring
|
||||
Returns the number of nodes in the list.
|
||||
:rtype: int
|
||||
%End
|
||||
|
||||
bool hasNamedNodes() const;
|
||||
%Docstring
|
||||
.. versionadded:: 2.16
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QList<QgsExpressionNode *> list();
|
||||
%Docstring
|
||||
Get a list of all the nodes.
|
||||
:rtype: list of QgsExpressionNode
|
||||
%End
|
||||
|
||||
QgsExpressionNode *at( int i );
|
||||
%Docstring
|
||||
Get the node at position i in the list.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
|
||||
QStringList names() const;
|
||||
%Docstring
|
||||
.. versionadded:: 2.16
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
NodeList *clone() const;
|
||||
%Docstring
|
||||
Creates a deep copy of this list. Ownership is transferred to the caller
|
||||
:rtype: NodeList
|
||||
%End
|
||||
|
||||
virtual QString dump() const;
|
||||
%Docstring
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
virtual ~QgsExpressionNode();
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const = 0;
|
||||
%Docstring
|
||||
Get the type of this node.
|
||||
|
||||
:return: The type of this node
|
||||
:rtype: QgsExpressionNode.NodeType
|
||||
%End
|
||||
|
||||
virtual QString dump() const = 0;
|
||||
%Docstring
|
||||
Dump this node into a serialized (part) of an expression.
|
||||
The returned expression does not necessarily literally match
|
||||
the original expression, it's just guaranteed to behave the same way.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
QVariant eval( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
%Docstring
|
||||
Evaluate this node with the given context and parent.
|
||||
This will return a cached value if it has been determined to be static
|
||||
during the prepare() execution.
|
||||
|
||||
.. versionadded:: 2.12
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode *clone() const = 0;
|
||||
%Docstring
|
||||
Generate a clone of this node.
|
||||
Ownership is transferred to the caller.
|
||||
|
||||
:return: a deep copy of this node.
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
|
||||
virtual QSet<QString> referencedColumns() const = 0;
|
||||
%Docstring
|
||||
Abstract virtual method which returns a list of columns required to
|
||||
evaluate this node.
|
||||
|
||||
When reimplementing this, you need to return any column that is required to
|
||||
evaluate this node and in addition recursively collect all the columns required
|
||||
to evaluate child nodes.
|
||||
|
||||
:return: A list of columns required to evaluate this expression
|
||||
:rtype: set of str
|
||||
%End
|
||||
|
||||
virtual QSet<QString> referencedVariables() const = 0;
|
||||
%Docstring
|
||||
Return a set of all variables which are used in this expression.
|
||||
:rtype: set of str
|
||||
%End
|
||||
|
||||
virtual bool needsGeometry() const = 0;
|
||||
%Docstring
|
||||
Abstract virtual method which returns if the geometry is required to evaluate
|
||||
this expression.
|
||||
|
||||
This needs to call `needsGeometry()` recursively on any child nodes.
|
||||
|
||||
:return: true if a geometry is required to evaluate this expression
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const = 0;
|
||||
%Docstring
|
||||
Returns true if this node can be evaluated for a static value. This is used during
|
||||
the prepare() step and in case it returns true, the value of this node will already
|
||||
be evaluated and the result cached (and therefore not re-evaluated in subsequent calls
|
||||
to eval()). In case this returns true, prepareNode() will never be called.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool prepare( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
%Docstring
|
||||
Prepare this node for evaluation.
|
||||
This will check if the node content is static and in this case cache the value.
|
||||
If it's not static it will call prepareNode() to allow the node to do initialization
|
||||
work like for example resolving a column name to an attribute index.
|
||||
|
||||
.. versionadded:: 2.12
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionnode.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
355
python/core/expression/qgsexpressionnodeimpl.sip
Normal file
355
python/core/expression/qgsexpressionnodeimpl.sip
Normal file
@ -0,0 +1,355 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionnodeimpl.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
class QgsExpressionNodeUnaryOperator : QgsExpressionNode
|
||||
{
|
||||
%Docstring
|
||||
A unary node is either negative as in boolean (not) or as in numbers (minus).
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
enum UnaryOperator
|
||||
{
|
||||
uoNot,
|
||||
uoMinus,
|
||||
};
|
||||
|
||||
QgsExpressionNodeUnaryOperator( QgsExpressionNodeUnaryOperator::UnaryOperator op, QgsExpressionNode *operand /Transfer/ );
|
||||
%Docstring
|
||||
A node unary operator is modifying the value of ``operand`` by negating it with ``op``.
|
||||
%End
|
||||
~QgsExpressionNodeUnaryOperator();
|
||||
|
||||
QgsExpressionNodeUnaryOperator::UnaryOperator op() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNodeUnaryOperator.UnaryOperator
|
||||
%End
|
||||
QgsExpressionNode *operand() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
QString text() const;
|
||||
%Docstring
|
||||
Returns a the name of this operator without the operands.
|
||||
I.e. "NOT" or "-"
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeBinaryOperator : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
enum BinaryOperator
|
||||
{
|
||||
// logical
|
||||
boOr,
|
||||
boAnd,
|
||||
|
||||
// comparison
|
||||
boEQ,
|
||||
boNE,
|
||||
boLE,
|
||||
boGE,
|
||||
boLT,
|
||||
boGT,
|
||||
boRegexp,
|
||||
boLike,
|
||||
boNotLike,
|
||||
boILike,
|
||||
boNotILike,
|
||||
boIs,
|
||||
boIsNot,
|
||||
|
||||
// math
|
||||
boPlus,
|
||||
boMinus,
|
||||
boMul,
|
||||
boDiv,
|
||||
boIntDiv,
|
||||
boMod,
|
||||
boPow,
|
||||
|
||||
// strings
|
||||
boConcat,
|
||||
};
|
||||
|
||||
QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::BinaryOperator op, QgsExpressionNode *opLeft /Transfer/, QgsExpressionNode *opRight /Transfer/ );
|
||||
%Docstring
|
||||
Binary combination of the left and the right with op.
|
||||
%End
|
||||
~QgsExpressionNodeBinaryOperator();
|
||||
|
||||
QgsExpressionNodeBinaryOperator::BinaryOperator op() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNodeBinaryOperator.BinaryOperator
|
||||
%End
|
||||
QgsExpressionNode *opLeft() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
QgsExpressionNode *opRight() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
int precedence() const;
|
||||
%Docstring
|
||||
:rtype: int
|
||||
%End
|
||||
bool leftAssociative() const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QString text() const;
|
||||
%Docstring
|
||||
Returns a the name of this operator without the operands.
|
||||
I.e. "AND", "OR", ...
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeInOperator : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsExpressionNodeInOperator( QgsExpressionNode *node /Transfer/, QgsExpressionNode::NodeList *list /Transfer/, bool notin = false );
|
||||
%Docstring
|
||||
This node tests if the result of ``node`` is in the result of ``list``. Optionally it can be inverted with ``notin`` which by default is false.
|
||||
%End
|
||||
virtual ~QgsExpressionNodeInOperator();
|
||||
|
||||
QgsExpressionNode *node() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode
|
||||
%End
|
||||
bool isNotIn() const;
|
||||
%Docstring
|
||||
:rtype: bool
|
||||
%End
|
||||
QgsExpressionNode::NodeList *list() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode.NodeList
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeFunction : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsExpressionNodeFunction( int fnIndex, QgsExpressionNode::NodeList *args /Transfer/ );
|
||||
%Docstring
|
||||
A function node consists of an index of the function in the global function array and
|
||||
a list of arguments that will be passed to it.
|
||||
%End
|
||||
|
||||
virtual ~QgsExpressionNodeFunction();
|
||||
|
||||
int fnIndex() const;
|
||||
%Docstring
|
||||
:rtype: int
|
||||
%End
|
||||
QgsExpressionNode::NodeList *args() const;
|
||||
%Docstring
|
||||
:rtype: QgsExpressionNode.NodeList
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
static bool validateParams( int fnIndex, QgsExpressionNode::NodeList *args, QString &error );
|
||||
%Docstring
|
||||
Tests whether the provided argument list is valid for the matching function
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeLiteral : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
QgsExpressionNodeLiteral( const QVariant &value );
|
||||
|
||||
QVariant value() const;
|
||||
%Docstring
|
||||
The value of the literal.
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeColumnRef : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
QgsExpressionNodeColumnRef( const QString &name );
|
||||
|
||||
QString name() const;
|
||||
%Docstring
|
||||
The name of the column.
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
};
|
||||
|
||||
class QgsExpressionNodeCondition : QgsExpressionNode
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
class WhenThen
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
WhenThen( QgsExpressionNode *whenExp, QgsExpressionNode *thenExp );
|
||||
%Docstring
|
||||
A combination of when and then. Simple as that.
|
||||
%End
|
||||
~WhenThen();
|
||||
|
||||
|
||||
QgsExpressionNodeCondition::WhenThen *clone() const;
|
||||
%Docstring
|
||||
Get a deep copy of this WhenThen combination.
|
||||
:rtype: QgsExpressionNodeCondition.WhenThen
|
||||
%End
|
||||
|
||||
private:
|
||||
WhenThen( const QgsExpressionNodeCondition::WhenThen &rh );
|
||||
};
|
||||
typedef QList<QgsExpressionNodeCondition::WhenThen *> WhenThenList;
|
||||
|
||||
QgsExpressionNodeCondition( QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp = 0 );
|
||||
%Docstring
|
||||
Create a new node with the given list of ``conditions`` and an optional ``elseExp`` expression.
|
||||
%End
|
||||
|
||||
|
||||
~QgsExpressionNodeCondition();
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const;
|
||||
virtual QSet<QString> referencedVariables() const;
|
||||
virtual bool needsGeometry() const;
|
||||
virtual QgsExpressionNode *clone() const;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/expression/qgsexpressionnodeimpl.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
|
||||
class QgsScopedExpressionFunction : QgsExpression::Function
|
||||
class QgsScopedExpressionFunction : QgsExpressionFunction
|
||||
{
|
||||
%Docstring
|
||||
Expression function for use within a QgsExpressionContextScope. This differs from a
|
||||
@ -39,7 +39,7 @@ class QgsScopedExpressionFunction : QgsExpression::Function
|
||||
%End
|
||||
|
||||
QgsScopedExpressionFunction( const QString &fnname,
|
||||
const QgsExpression::ParameterList ¶ms,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool usesGeometry = false,
|
||||
@ -61,11 +61,11 @@ class QgsScopedExpressionFunction : QgsExpression::Function
|
||||
:rtype: QgsScopedExpressionFunction
|
||||
%End
|
||||
|
||||
virtual bool usesGeometry( const QgsExpression::NodeFunction *node ) const;
|
||||
virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
|
||||
|
||||
virtual QSet<QString> referencedColumns( const QgsExpression::NodeFunction *node ) const;
|
||||
virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
|
||||
|
||||
virtual bool isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
};
|
||||
|
||||
@ -240,7 +240,7 @@ A static variable can be cached for the lifetime of a context
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
QgsExpression::Function *function( const QString &name ) const;
|
||||
QgsExpressionFunction *function( const QString &name ) const;
|
||||
%Docstring
|
||||
Retrieves a function from the scope.
|
||||
\param name function name
|
||||
@ -248,7 +248,7 @@ A static variable can be cached for the lifetime of a context
|
||||
.. seealso:: hasFunction()
|
||||
.. seealso:: functionNames()
|
||||
.. seealso:: variable()
|
||||
:rtype: QgsExpression.Function
|
||||
:rtype: QgsExpressionFunction
|
||||
%End
|
||||
|
||||
QStringList functionNames() const;
|
||||
@ -492,7 +492,7 @@ class QgsExpressionContext
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
QgsExpression::Function *function( const QString &name ) const;
|
||||
QgsExpressionFunction *function( const QString &name ) const;
|
||||
%Docstring
|
||||
Fetches a matching function from the context. The function will be fetched
|
||||
from the last scope contained within the context which has a matching
|
||||
@ -500,7 +500,7 @@ class QgsExpressionContext
|
||||
\param name function name
|
||||
:return: function if contained by the context, otherwise null.
|
||||
.. seealso:: hasFunction
|
||||
:rtype: QgsExpression.Function
|
||||
:rtype: QgsExpressionFunction
|
||||
%End
|
||||
|
||||
int scopeCount() const;
|
||||
|
@ -1,93 +0,0 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsvertexmarker.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsVertexMarker : QgsMapCanvasItem
|
||||
{
|
||||
%Docstring
|
||||
A class for marking vertices of features using e.g. circles or 'x'.
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsvertexmarker.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
enum IconType
|
||||
{
|
||||
ICON_NONE,
|
||||
ICON_CROSS,
|
||||
ICON_X,
|
||||
ICON_BOX,
|
||||
ICON_CIRCLE
|
||||
};
|
||||
|
||||
QgsVertexMarker( QgsMapCanvas *mapCanvas /TransferThis/ );
|
||||
|
||||
void setCenter( const QgsPoint &point );
|
||||
|
||||
void setIconType( int iconType );
|
||||
|
||||
void setIconSize( int iconSize );
|
||||
|
||||
void setColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the stroke ``color`` for the marker.
|
||||
.. seealso:: color()
|
||||
.. seealso:: setFillColor()
|
||||
%End
|
||||
|
||||
QColor color() const;
|
||||
%Docstring
|
||||
Returns the stroke color for the marker.
|
||||
.. seealso:: setColor()
|
||||
.. seealso:: fillColor()
|
||||
.. versionadded:: 3.0
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setFillColor( const QColor &color );
|
||||
%Docstring
|
||||
Sets the fill ``color`` for the marker. This setting only
|
||||
applies to some icon types.
|
||||
.. versionadded:: 3.0
|
||||
.. seealso:: fillColor()
|
||||
.. seealso:: setColor()
|
||||
%End
|
||||
|
||||
QColor fillColor() const;
|
||||
%Docstring
|
||||
Returns the fill ``color`` for the marker. This setting only
|
||||
applies to some icon types.
|
||||
.. versionadded:: 3.0
|
||||
.. seealso:: setFillColor()
|
||||
.. seealso:: color()
|
||||
:rtype: QColor
|
||||
%End
|
||||
|
||||
void setPenWidth( int width );
|
||||
|
||||
virtual void paint( QPainter *p );
|
||||
|
||||
|
||||
virtual QRectF boundingRect() const;
|
||||
|
||||
|
||||
virtual void updatePosition();
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/qgsvertexmarker.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -158,11 +158,12 @@ SET(QGIS_ANALYSIS_HDRS
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../core/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../core/geometry
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../core/raster
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../core/symbology-ng
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||
${CMAKE_SOURCE_DIR}/src/core/symbology-ng
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/analysis
|
||||
interpolation
|
||||
|
@ -87,6 +87,11 @@ SET(QGIS_CORE_SRCS
|
||||
annotations/qgssvgannotation.cpp
|
||||
annotations/qgstextannotation.cpp
|
||||
|
||||
expression/qgsexpression.cpp
|
||||
expression/qgsexpressionnode.cpp
|
||||
expression/qgsexpressionnodeimpl.cpp
|
||||
expression/qgsexpressionfunction.cpp
|
||||
|
||||
processing/qgsnativealgorithms.cpp
|
||||
processing/qgsprocessingalgorithm.cpp
|
||||
processing/qgsprocessingparameters.cpp
|
||||
@ -146,7 +151,6 @@ SET(QGIS_CORE_SRCS
|
||||
qgseditformconfig.cpp
|
||||
qgsellipsoidutils.cpp
|
||||
qgserror.cpp
|
||||
qgsexpression.cpp
|
||||
qgsexpressioncontext.cpp
|
||||
qgsexpressionfieldbuffer.cpp
|
||||
qgsfeature.cpp
|
||||
@ -697,6 +701,11 @@ SET(QGIS_CORE_HDRS
|
||||
${CMAKE_BINARY_DIR}/qgsconfig.h
|
||||
../plugins/qgisplugin.h
|
||||
|
||||
expression/qgsexpression.h
|
||||
expression/qgsexpressionnode.h
|
||||
expression/qgsexpressionnodeimpl.h
|
||||
expression/qgsexpressionfunction.h
|
||||
|
||||
qgis.h
|
||||
qgis_sip.h
|
||||
qgsaction.h
|
||||
@ -736,7 +745,6 @@ SET(QGIS_CORE_HDRS
|
||||
qgsellipsoidutils.h
|
||||
qgserror.h
|
||||
qgsexception.h
|
||||
qgsexpression.h
|
||||
qgsexpressioncontext.h
|
||||
qgsexpressioncontextgenerator.h
|
||||
qgsexpressionfieldbuffer.h
|
||||
@ -1019,6 +1027,7 @@ INCLUDE_DIRECTORIES(
|
||||
composer
|
||||
dxf
|
||||
effects
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
fieldformatter
|
||||
geometry
|
||||
layertree
|
||||
|
File diff suppressed because it is too large
Load Diff
552
src/core/expression/qgsexpression.h
Normal file
552
src/core/expression/qgsexpression.h
Normal file
@ -0,0 +1,552 @@
|
||||
/***************************************************************************
|
||||
qgsexpression.h
|
||||
-------------------
|
||||
begin : August 2011
|
||||
copyright : (C) 2011 Martin Dobias
|
||||
email : wonder.sk at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSEXPRESSION_H
|
||||
#define QGSEXPRESSION_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include <QMetaType>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
#include <QList>
|
||||
#include <QDomDocument>
|
||||
#include <QCoreApplication>
|
||||
#include <QSet>
|
||||
#include <functional>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgsinterval.h"
|
||||
|
||||
class QgsFeature;
|
||||
class QgsGeometry;
|
||||
class QgsOgcUtils;
|
||||
class QgsVectorLayer;
|
||||
class QgsVectorDataProvider;
|
||||
class QgsField;
|
||||
class QgsFields;
|
||||
class QgsDistanceArea;
|
||||
class QDomElement;
|
||||
class QgsExpressionContext;
|
||||
class QgsExpressionPrivate;
|
||||
class QgsExpressionNode;
|
||||
class QgsExpressionFunction;
|
||||
|
||||
/** \ingroup core
|
||||
Class for parsing and evaluation of expressions (formerly called "search strings").
|
||||
The expressions try to follow both syntax and semantics of SQL expressions.
|
||||
|
||||
Usage:
|
||||
\code{.cpp}
|
||||
QgsExpression exp("gid*2 > 10 and type not in ('D','F'));
|
||||
if (exp.hasParserError())
|
||||
{
|
||||
// show error message with parserErrorString() and exit
|
||||
}
|
||||
QVariant result = exp.evaluate(feature, fields);
|
||||
if (exp.hasEvalError())
|
||||
{
|
||||
// show error message with evalErrorString()
|
||||
}
|
||||
else
|
||||
{
|
||||
// examine the result
|
||||
}
|
||||
\endcode
|
||||
|
||||
Three Value Logic
|
||||
=================
|
||||
|
||||
Similarly to SQL, this class supports three-value logic: true/false/unknown.
|
||||
Unknown value may be a result of operations with missing data (NULL). Please note
|
||||
that NULL is different value than zero or an empty string. For example
|
||||
3 > NULL returns unknown.
|
||||
|
||||
There is no special (three-value) 'boolean' type: true/false is represented as
|
||||
1/0 integer, unknown value is represented the same way as NULL values: NULL QVariant.
|
||||
|
||||
Performance
|
||||
===========
|
||||
|
||||
For better performance with many evaluations you may first call prepare(fields) function
|
||||
to find out indices of columns and then repeatedly call evaluate(feature).
|
||||
|
||||
Type conversion
|
||||
===============
|
||||
|
||||
Operators and functions that expect arguments to be of a particular
|
||||
type automatically convert the arguments to that type, e.g. sin('2.1') will convert
|
||||
the argument to a double, length(123) will first convert the number to a string.
|
||||
Explicit conversion can be achieved with to_int, to_real, to_string functions.
|
||||
If implicit or explicit conversion is invalid, the evaluation returns an error.
|
||||
Comparison operators do numeric comparison in case both operators are numeric (int/double)
|
||||
or they can be converted to numeric types.
|
||||
|
||||
Implicit sharing
|
||||
================
|
||||
|
||||
This class is implicitly shared, copying has a very low overhead.
|
||||
It is normally preferable to call `QgsExpression( otherExpression )` instead of
|
||||
`QgsExpression( otherExpression.expression() )`. A deep copy will only be made
|
||||
when prepare() is called. For usage this means mainly, that you should
|
||||
normally keep an unprepared master copy of a QgsExpression and whenever using it
|
||||
with a particular QgsFeatureIterator copy it just before and prepare it using the
|
||||
same context as the iterator.
|
||||
|
||||
Implicit sharing was added in 2.14
|
||||
|
||||
*/
|
||||
|
||||
class CORE_EXPORT QgsExpression
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS( QgsExpression )
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new expression based on the provided string.
|
||||
* The string will immediately be parsed. For optimization
|
||||
* prepare() should always be called before every
|
||||
* loop in which this expression is used.
|
||||
*/
|
||||
QgsExpression( const QString &expr );
|
||||
|
||||
/**
|
||||
* Create a copy of this expression. This is preferred
|
||||
* over recreating an expression from a string since
|
||||
* it does not need to be re-parsed.
|
||||
*/
|
||||
QgsExpression( const QgsExpression &other );
|
||||
|
||||
/**
|
||||
* Create a copy of this expression. This is preferred
|
||||
* over recreating an expression from a string since
|
||||
* it does not need to be re-parsed.
|
||||
*/
|
||||
QgsExpression &operator=( const QgsExpression &other );
|
||||
|
||||
/**
|
||||
* Create an empty expression.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsExpression();
|
||||
|
||||
~QgsExpression();
|
||||
|
||||
/**
|
||||
* Compares two expressions. The operator returns true
|
||||
* if the expression string is equal.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool operator==( const QgsExpression &other ) const;
|
||||
|
||||
/**
|
||||
* Checks if this expression is valid.
|
||||
* A valid expression could be parsed but does not necessarily evaluate properly.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
//! Returns true if an error occurred when parsing the input expression
|
||||
bool hasParserError() const;
|
||||
//! Returns parser error
|
||||
QString parserErrorString() const;
|
||||
|
||||
//! Returns root node of the expression. Root node is null is parsing has failed
|
||||
const QgsExpressionNode *rootNode() const;
|
||||
|
||||
/** Get the expression ready for evaluation - find out column indexes.
|
||||
* \param context context for preparing expression
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
bool prepare( const QgsExpressionContext *context );
|
||||
|
||||
/**
|
||||
* Get list of columns referenced by the expression.
|
||||
*
|
||||
* \note If the returned list contains the QgsFeatureRequest::AllAttributes constant then
|
||||
* all attributes from the layer are required for evaluation of the expression.
|
||||
* QgsFeatureRequest::setSubsetOfAttributes automatically handles this case.
|
||||
*
|
||||
* \see referencedAttributeIndexes()
|
||||
*/
|
||||
QSet<QString> referencedColumns() const;
|
||||
|
||||
/**
|
||||
* Return a list of all variables which are used in this expression.
|
||||
* If the list contains a NULL QString, there is a variable name used
|
||||
* which is determined at runtime.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QSet<QString> referencedVariables() const;
|
||||
|
||||
/**
|
||||
* Return a list of field name indexes obtained from the provided fields.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QSet<int> referencedAttributeIndexes( const QgsFields &fields ) const;
|
||||
|
||||
//! Returns true if the expression uses feature geometry for some computation
|
||||
bool needsGeometry() const;
|
||||
|
||||
// evaluation
|
||||
|
||||
/** Evaluate the feature and return the result.
|
||||
* \note this method does not expect that prepare() has been called on this instance
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
QVariant evaluate();
|
||||
|
||||
/** Evaluate the expression against the specified context and return the result.
|
||||
* \param context context for evaluating expression
|
||||
* \note prepare() should be called before calling this method.
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
QVariant evaluate( const QgsExpressionContext *context );
|
||||
|
||||
//! Returns true if an error occurred when evaluating last input
|
||||
bool hasEvalError() const;
|
||||
//! Returns evaluation error
|
||||
QString evalErrorString() const;
|
||||
//! Set evaluation error (used internally by evaluation functions)
|
||||
void setEvalErrorString( const QString &str );
|
||||
|
||||
/** Checks whether an expression consists only of a single field reference
|
||||
* \since QGIS 2.9
|
||||
*/
|
||||
bool isField() const;
|
||||
|
||||
/** Tests whether a string is a valid expression.
|
||||
* \param text string to test
|
||||
* \param context optional expression context
|
||||
* \param errorMessage will be filled with any error message from the validation
|
||||
* \returns true if string is a valid expression
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
static bool checkExpression( const QString &text, const QgsExpressionContext *context, QString &errorMessage SIP_OUT );
|
||||
|
||||
/**
|
||||
* Set the expression string, will reset the whole internal structure.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void setExpression( const QString &expression );
|
||||
|
||||
//! Return the original, unmodified expression string.
|
||||
//! If there was none supplied because it was constructed by sole
|
||||
//! API calls, dump() will be used to create one instead.
|
||||
QString expression() const;
|
||||
|
||||
//! Return an expression string, constructed from the internal
|
||||
//! abstract syntax tree. This does not contain any nice whitespace
|
||||
//! formatting or comments. In general it is preferable to use
|
||||
//! expression() instead.
|
||||
QString dump() const;
|
||||
|
||||
/** Return calculator used for distance and area calculations
|
||||
* (used by $length, $area and $perimeter functions only)
|
||||
* \see setGeomCalculator()
|
||||
* \see distanceUnits()
|
||||
* \see areaUnits()
|
||||
*/
|
||||
QgsDistanceArea *geomCalculator();
|
||||
|
||||
/** Sets the geometry calculator used for distance and area calculations in expressions.
|
||||
* (used by $length, $area and $perimeter functions only). By default, no geometry
|
||||
* calculator is set and all distance and area calculations are performed using simple
|
||||
* cartesian methods (ie no ellipsoidal calculations).
|
||||
* \param calc geometry calculator. Ownership is not transferred. Set to a nullptr to force
|
||||
* cartesian calculations.
|
||||
* \see geomCalculator()
|
||||
*/
|
||||
void setGeomCalculator( const QgsDistanceArea *calc );
|
||||
|
||||
/** Returns the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
|
||||
* \note distances are only converted when a geomCalculator() has been set
|
||||
* \since QGIS 2.14
|
||||
* \see setDistanceUnits()
|
||||
* \see areaUnits()
|
||||
*/
|
||||
QgsUnitTypes::DistanceUnit distanceUnits() const;
|
||||
|
||||
/** Sets the desired distance units for calculations involving geomCalculator(), e.g., "$length" and "$perimeter".
|
||||
* \note distances are only converted when a geomCalculator() has been set
|
||||
* \since QGIS 2.14
|
||||
* \see distanceUnits()
|
||||
* \see setAreaUnits()
|
||||
*/
|
||||
void setDistanceUnits( QgsUnitTypes::DistanceUnit unit );
|
||||
|
||||
/** Returns the desired areal units for calculations involving geomCalculator(), e.g., "$area".
|
||||
* \note areas are only converted when a geomCalculator() has been set
|
||||
* \since QGIS 2.14
|
||||
* \see setAreaUnits()
|
||||
* \see distanceUnits()
|
||||
*/
|
||||
QgsUnitTypes::AreaUnit areaUnits() const;
|
||||
|
||||
/** Sets the desired areal units for calculations involving geomCalculator(), e.g., "$area".
|
||||
* \note areas are only converted when a geomCalculator() has been set
|
||||
* \since QGIS 2.14
|
||||
* \see areaUnits()
|
||||
* \see setDistanceUnits()
|
||||
*/
|
||||
void setAreaUnits( QgsUnitTypes::AreaUnit unit );
|
||||
|
||||
/** This function replaces each expression between [% and %]
|
||||
* in the string with the result of its evaluation with the specified context
|
||||
*
|
||||
* Additional substitutions can be passed through the substitutionMap parameter
|
||||
* \param action The source string in which placeholders should be replaced.
|
||||
* \param context Expression context
|
||||
* \param distanceArea Optional QgsDistanceArea. If specified, the QgsDistanceArea is used for distance
|
||||
* and area conversion
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
static QString replaceExpressionText( const QString &action, const QgsExpressionContext *context,
|
||||
const QgsDistanceArea *distanceArea = nullptr );
|
||||
|
||||
/** Attempts to evaluate a text string as an expression to a resultant double
|
||||
* value.
|
||||
* \param text text to evaluate as expression
|
||||
* \param fallbackValue value to return if text can not be evaluated as a double
|
||||
* \returns evaluated double value, or fallback value
|
||||
* \since QGIS 2.7
|
||||
* \note this method is inefficient for bulk evaluation of expressions, it is intended
|
||||
* for one-off evaluations only.
|
||||
*/
|
||||
static double evaluateToDouble( const QString &text, const double fallbackValue );
|
||||
|
||||
enum SpatialOperator
|
||||
{
|
||||
soBbox,
|
||||
soIntersects,
|
||||
soContains,
|
||||
soCrosses,
|
||||
soEquals,
|
||||
soDisjoint,
|
||||
soOverlaps,
|
||||
soTouches,
|
||||
soWithin,
|
||||
};
|
||||
|
||||
//! \note not available in Python bindings
|
||||
static QList<QgsExpressionFunction *> sFunctions SIP_SKIP;
|
||||
static const QList<QgsExpressionFunction *> &Functions();
|
||||
|
||||
//! \note not available in Python bindings
|
||||
static QStringList sBuiltinFunctions SIP_SKIP;
|
||||
static const QStringList &BuiltinFunctions();
|
||||
|
||||
/** Registers a function to the expression engine. This is required to allow expressions to utilize the function.
|
||||
* \param function function to register
|
||||
* \param transferOwnership set to true to transfer ownership of function to expression engine
|
||||
* \returns true on successful registration
|
||||
* \see unregisterFunction
|
||||
*/
|
||||
static bool registerFunction( QgsExpressionFunction *function, bool transferOwnership = false );
|
||||
|
||||
/** Unregisters a function from the expression engine. The function will no longer be usable in expressions.
|
||||
* \param name function name
|
||||
* \see registerFunction
|
||||
*/
|
||||
static bool unregisterFunction( const QString &name );
|
||||
|
||||
//! List of functions owned by the expression engine
|
||||
//! \note not available in Python bindings
|
||||
static QList<QgsExpressionFunction *> sOwnedFunctions SIP_SKIP;
|
||||
|
||||
/** Deletes all registered functions whose ownership have been transferred to the expression engine.
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
static void cleanRegisteredFunctions();
|
||||
|
||||
//! tells whether the identifier is a name of existing function
|
||||
static bool isFunctionName( const QString &name );
|
||||
|
||||
//! return index of the function in Functions array
|
||||
static int functionIndex( const QString &name );
|
||||
|
||||
/** Returns the number of functions defined in the parser
|
||||
* \returns The number of function defined in the parser.
|
||||
*/
|
||||
static int functionCount();
|
||||
|
||||
/** Returns a quoted column reference (in double quotes)
|
||||
* \see quotedString()
|
||||
* \see quotedValue()
|
||||
*/
|
||||
static QString quotedColumnRef( QString name );
|
||||
|
||||
/** Returns a quoted version of a string (in single quotes)
|
||||
* \see quotedValue()
|
||||
* \see quotedColumnRef()
|
||||
*/
|
||||
static QString quotedString( QString text );
|
||||
|
||||
/** Returns a string representation of a literal value, including appropriate
|
||||
* quotations where required.
|
||||
* \param value value to convert to a string representation
|
||||
* \since QGIS 2.14
|
||||
* \see quotedString()
|
||||
* \see quotedColumnRef()
|
||||
*/
|
||||
static QString quotedValue( const QVariant &value );
|
||||
|
||||
/** Returns a string representation of a literal value, including appropriate
|
||||
* quotations where required.
|
||||
* \param value value to convert to a string representation
|
||||
* \param type value type
|
||||
* \since QGIS 2.14
|
||||
* \see quotedString()
|
||||
* \see quotedColumnRef()
|
||||
*/
|
||||
static QString quotedValue( const QVariant &value, QVariant::Type type );
|
||||
|
||||
//////
|
||||
|
||||
/** Returns the help text for a specified function.
|
||||
* \param name function name
|
||||
* \see variableHelpText()
|
||||
*/
|
||||
static QString helpText( QString name );
|
||||
|
||||
/** Returns the help text for a specified variable.
|
||||
* \param variableName name of variable
|
||||
* \param showValue set to true to include current value of variable in help text
|
||||
* \param value current value of variable to show in help text
|
||||
* \see helpText()
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
static QString variableHelpText( const QString &variableName, bool showValue = true, const QVariant &value = QVariant() );
|
||||
|
||||
/** Returns the translated name for a function group.
|
||||
* \param group untranslated group name
|
||||
*/
|
||||
static QString group( const QString &group );
|
||||
|
||||
/** Formats an expression result for friendly display to the user. Truncates the result to a sensible
|
||||
* length, and presents text representations of non numeric/text types (e.g., geometries and features).
|
||||
* \param value expression result to format
|
||||
* \returns formatted string, may contain HTML formatting characters
|
||||
* \since QGIS 2.14
|
||||
*/
|
||||
static QString formatPreviewString( const QVariant &value );
|
||||
|
||||
private:
|
||||
void initGeomCalculator();
|
||||
|
||||
struct HelpArg SIP_SKIP
|
||||
{
|
||||
HelpArg( const QString &arg, const QString &desc, bool descOnly = false, bool syntaxOnly = false,
|
||||
bool optional = false, const QString &defaultVal = QString() )
|
||||
: mArg( arg )
|
||||
, mDescription( desc )
|
||||
, mDescOnly( descOnly )
|
||||
, mSyntaxOnly( syntaxOnly )
|
||||
, mOptional( optional )
|
||||
, mDefaultVal( defaultVal )
|
||||
{}
|
||||
|
||||
QString mArg;
|
||||
QString mDescription;
|
||||
bool mDescOnly;
|
||||
bool mSyntaxOnly;
|
||||
bool mOptional;
|
||||
QString mDefaultVal;
|
||||
};
|
||||
|
||||
struct HelpExample SIP_SKIP
|
||||
{
|
||||
HelpExample( const QString &expression, const QString &returns, const QString ¬e = QString::null )
|
||||
: mExpression( expression )
|
||||
, mReturns( returns )
|
||||
, mNote( note )
|
||||
{}
|
||||
|
||||
QString mExpression;
|
||||
QString mReturns;
|
||||
QString mNote;
|
||||
};
|
||||
|
||||
struct HelpVariant SIP_SKIP
|
||||
{
|
||||
HelpVariant( const QString &name, const QString &description,
|
||||
const QList<QgsExpression::HelpArg> &arguments = QList<QgsExpression::HelpArg>(),
|
||||
bool variableLenArguments = false,
|
||||
const QList<QgsExpression::HelpExample> &examples = QList<QgsExpression::HelpExample>(),
|
||||
const QString ¬es = QString::null )
|
||||
: mName( name )
|
||||
, mDescription( description )
|
||||
, mArguments( arguments )
|
||||
, mVariableLenArguments( variableLenArguments )
|
||||
, mExamples( examples )
|
||||
, mNotes( notes )
|
||||
{}
|
||||
|
||||
QString mName;
|
||||
QString mDescription;
|
||||
QList<QgsExpression::HelpArg> mArguments;
|
||||
bool mVariableLenArguments;
|
||||
QList<QgsExpression::HelpExample> mExamples;
|
||||
QString mNotes;
|
||||
};
|
||||
|
||||
struct Help SIP_SKIP
|
||||
{
|
||||
Help() {}
|
||||
|
||||
Help( const QString &name, const QString &type, const QString &description, const QList<QgsExpression::HelpVariant> &variants )
|
||||
: mName( name )
|
||||
, mType( type )
|
||||
, mDescription( description )
|
||||
, mVariants( variants )
|
||||
{}
|
||||
|
||||
QString mName;
|
||||
QString mType;
|
||||
QString mDescription;
|
||||
QList<QgsExpression::HelpVariant> mVariants;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper for implicit sharing. When called will create
|
||||
* a new deep copy of this expression.
|
||||
*
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
void detach() SIP_SKIP;
|
||||
|
||||
QgsExpressionPrivate *d = nullptr;
|
||||
|
||||
static QHash<QString, Help> sFunctionHelpTexts;
|
||||
static QHash<QString, QString> sVariableHelpTexts;
|
||||
static QHash<QString, QString> sGroups;
|
||||
|
||||
//! \note not available in Python bindings
|
||||
static void initFunctionHelp() SIP_SKIP;
|
||||
//! \note not available in Python bindings
|
||||
static void initVariableHelp() SIP_SKIP;
|
||||
|
||||
friend class QgsOgcUtils;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QgsExpression )
|
||||
|
||||
#endif // QGSEXPRESSION_H
|
7
src/core/expression/qgsexpressionfunction.cpp
Normal file
7
src/core/expression/qgsexpressionfunction.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "qgsexpressionfunction.h"
|
||||
#include "qgsexpression.h"
|
||||
|
||||
const QString QgsExpressionFunction::helpText() const
|
||||
{
|
||||
return mHelpText.isEmpty() ? QgsExpression::helpText( mName ) : mHelpText;
|
||||
}
|
438
src/core/expression/qgsexpressionfunction.h
Normal file
438
src/core/expression/qgsexpressionfunction.h
Normal file
@ -0,0 +1,438 @@
|
||||
#ifndef QGSEXPRESSIONFUNCTION_H
|
||||
#define QGSEXPRESSIONFUNCTION_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QSet>
|
||||
|
||||
#include "qgis.h"
|
||||
#include "qgis_core.h"
|
||||
|
||||
class QgsExpressionNodeFunction;
|
||||
class QgsExpression;
|
||||
class QgsExpressionContext;
|
||||
|
||||
/** \ingroup core
|
||||
* A abstract base class for defining QgsExpression functions.
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionFunction
|
||||
{
|
||||
public:
|
||||
|
||||
/** Function definition for evaluation against an expression context, using a list of values as parameters to the function.
|
||||
*/
|
||||
typedef QVariant( *FcnEval )( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) SIP_SKIP;
|
||||
|
||||
/** \ingroup core
|
||||
* Represents a single parameter passed to a function.
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
class CORE_EXPORT Parameter
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructor for Parameter.
|
||||
* \param name parameter name, used when named parameter are specified in an expression
|
||||
* \param optional set to true if parameter should be optional
|
||||
* \param defaultValue default value to use for optional parameters
|
||||
*/
|
||||
Parameter( const QString &name,
|
||||
bool optional = false,
|
||||
const QVariant &defaultValue = QVariant() )
|
||||
: mName( name )
|
||||
, mOptional( optional )
|
||||
, mDefaultValue( defaultValue )
|
||||
{}
|
||||
|
||||
//! Returns the name of the parameter.
|
||||
QString name() const { return mName; }
|
||||
|
||||
//! Returns true if the parameter is optional.
|
||||
bool optional() const { return mOptional; }
|
||||
|
||||
//! Returns the default value for the parameter.
|
||||
QVariant defaultValue() const { return mDefaultValue; }
|
||||
|
||||
bool operator==( const QgsExpressionFunction::Parameter &other ) const
|
||||
{
|
||||
return ( QString::compare( mName, other.mName, Qt::CaseInsensitive ) == 0 );
|
||||
}
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
bool mOptional;
|
||||
QVariant mDefaultValue;
|
||||
};
|
||||
|
||||
//! List of parameters, used for function definition
|
||||
typedef QList< QgsExpressionFunction::Parameter > ParameterList;
|
||||
|
||||
//! Constructor for function which uses unnamed parameters
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
int params,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false )
|
||||
: mName( fnname )
|
||||
, mParams( params )
|
||||
, mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
|
||||
, mHelpText( helpText )
|
||||
, mLazyEval( lazyEval )
|
||||
, mHandlesNull( handlesNull )
|
||||
, mIsContextual( isContextual )
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for function which uses unnamed parameters and group list
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
int params,
|
||||
const QStringList &groups,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false )
|
||||
: mName( fnname )
|
||||
, mParams( params )
|
||||
, mGroups( groups )
|
||||
, mHelpText( helpText )
|
||||
, mLazyEval( lazyEval )
|
||||
, mHandlesNull( handlesNull )
|
||||
, mIsContextual( isContextual )
|
||||
{
|
||||
}
|
||||
|
||||
/** Constructor for function which uses named parameter list.
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false )
|
||||
: mName( fnname )
|
||||
, mParams( 0 )
|
||||
, mParameterList( params )
|
||||
, mGroups( group.isEmpty() ? QStringList() : QStringList() << group )
|
||||
, mHelpText( helpText )
|
||||
, mLazyEval( lazyEval )
|
||||
, mHandlesNull( handlesNull )
|
||||
, mIsContextual( isContextual )
|
||||
{}
|
||||
|
||||
/** Constructor for function which uses named parameter list and group list.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QStringList &groups,
|
||||
const QString &helpText = QString(),
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = false )
|
||||
: mName( fnname )
|
||||
, mParams( 0 )
|
||||
, mParameterList( params )
|
||||
, mGroups( groups )
|
||||
, mHelpText( helpText )
|
||||
, mLazyEval( lazyEval )
|
||||
, mHandlesNull( handlesNull )
|
||||
, mIsContextual( isContextual )
|
||||
{}
|
||||
|
||||
virtual ~QgsExpressionFunction() = default;
|
||||
|
||||
//! The name of the function.
|
||||
QString name() const { return mName; }
|
||||
|
||||
//! The number of parameters this function takes.
|
||||
int params() const { return mParameterList.isEmpty() ? mParams : mParameterList.count(); }
|
||||
|
||||
//! The minimum number of parameters this function takes.
|
||||
int minParams() const
|
||||
{
|
||||
if ( mParameterList.isEmpty() )
|
||||
return mParams;
|
||||
|
||||
int min = 0;
|
||||
Q_FOREACH ( const Parameter ¶m, mParameterList )
|
||||
{
|
||||
if ( !param.optional() )
|
||||
min++;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/** Returns the list of named parameters for the function, if set.
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
const QgsExpressionFunction::ParameterList ¶meters() const { return mParameterList; }
|
||||
|
||||
//! Does this function use a geometry object.
|
||||
virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const;
|
||||
|
||||
/**
|
||||
* Returns a list of possible aliases for the function. These include
|
||||
* other permissible names for the function, e.g., deprecated names.
|
||||
* \returns list of known aliases
|
||||
* \since QGIS 2.9
|
||||
*/
|
||||
virtual QStringList aliases() const;
|
||||
|
||||
/**
|
||||
* True if this function should use lazy evaluation. Lazy evaluation functions take QgsExpression::Node objects
|
||||
* rather than the node results when called. You can use node->eval(parent, feature) to evaluate the node and return the result
|
||||
* Functions are non lazy default and will be given the node return value when called.
|
||||
*/
|
||||
bool lazyEval() const { return mLazyEval; }
|
||||
|
||||
/**
|
||||
* Will be called during prepare to determine if the function is static.
|
||||
* A function is static if it will return the same value for every feature with different
|
||||
* attributes and/or geometry.
|
||||
*
|
||||
* By default this will return true, if all arguments that have been passed to the function
|
||||
* are also static.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
/**
|
||||
* This will be called during the prepare step() of an expression if it is not static.
|
||||
*
|
||||
* This can be used by functions to do any preparation steps that might help to speedup the upcoming
|
||||
* evaluation.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const;
|
||||
|
||||
/**
|
||||
* Returns a set of field names which are required for this function.
|
||||
* May contain QgsFeatureRequest::AllAttributes to signal that all
|
||||
* attributes are required.
|
||||
* If in doubt this will return more fields than strictly required.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const;
|
||||
|
||||
/** Returns whether the function is only available if provided by a QgsExpressionContext object.
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
bool isContextual() const { return mIsContextual; }
|
||||
|
||||
/** Returns true if the function is deprecated and should not be presented as a valid option
|
||||
* to users in expression builders.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool isDeprecated() const;
|
||||
|
||||
/** Returns the first group which the function belongs to.
|
||||
* \note consider using groups() instead, as some functions naturally belong in multiple groups
|
||||
*/
|
||||
QString group() const { return mGroups.isEmpty() ? QString() : mGroups.at( 0 ); }
|
||||
|
||||
/** Returns a list of the groups the function belongs to.
|
||||
* \since QGIS 3.0
|
||||
* \see group()
|
||||
*/
|
||||
QStringList groups() const { return mGroups; }
|
||||
|
||||
//! The help text for the function.
|
||||
const QString helpText() const;
|
||||
|
||||
/** Returns result of evaluating the function.
|
||||
* \param values list of values passed to the function
|
||||
* \param context context expression is being evaluated against
|
||||
* \param parent parent expression
|
||||
* \returns result of function
|
||||
*/
|
||||
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) = 0;
|
||||
|
||||
bool operator==( const QgsExpressionFunction &other ) const;
|
||||
|
||||
virtual bool handlesNull() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This will return true if all the params for the provided function \a node are static within the
|
||||
* constraints imposed by the \a context within the given \a parent.
|
||||
*
|
||||
* This can be used as callback for custom implementations of subclasses. It is the default for implementation
|
||||
* for StaticFunction::isStatic.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static bool allParamsStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context );
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
int mParams;
|
||||
QgsExpressionFunction::ParameterList mParameterList;
|
||||
QStringList mGroups;
|
||||
QString mHelpText;
|
||||
bool mLazyEval;
|
||||
bool mHandlesNull;
|
||||
bool mIsContextual; //if true function is only available through an expression context
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
* c++ helper class for defining QgsExpression functions.
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
#ifndef SIP_RUN
|
||||
class QgsStaticExpressionFunction : public QgsExpressionFunction
|
||||
{
|
||||
public:
|
||||
|
||||
/** Static function for evaluation against a QgsExpressionContext, using an unnamed list of parameter values.
|
||||
*/
|
||||
QgsStaticExpressionFunction( const QString &fnname,
|
||||
int params,
|
||||
FcnEval fcn,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool usesGeometry = false,
|
||||
const QSet<QString> &referencedColumns = QSet<QString>(),
|
||||
bool lazyEval = false,
|
||||
const QStringList &aliases = QStringList(),
|
||||
bool handlesNull = false )
|
||||
: QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
|
||||
, mFnc( fcn )
|
||||
, mAliases( aliases )
|
||||
, mUsesGeometry( usesGeometry )
|
||||
, mReferencedColumns( referencedColumns )
|
||||
{
|
||||
}
|
||||
|
||||
/** Static function for evaluation against a QgsExpressionContext, using a named list of parameter values.
|
||||
*/
|
||||
QgsStaticExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
FcnEval fcn,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool usesGeometry = false,
|
||||
const QSet<QString> &referencedColumns = QSet<QString>(),
|
||||
bool lazyEval = false,
|
||||
const QStringList &aliases = QStringList(),
|
||||
bool handlesNull = false )
|
||||
: QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull )
|
||||
, mFnc( fcn )
|
||||
, mAliases( aliases )
|
||||
, mUsesGeometry( usesGeometry )
|
||||
, mReferencedColumns( referencedColumns )
|
||||
{}
|
||||
|
||||
/**
|
||||
* Static function for evaluation against a QgsExpressionContext, using a named list of parameter values.
|
||||
*
|
||||
* Lambda functions can be provided that will be called to determine if a geometry is used an which
|
||||
* columns are referenced.
|
||||
* This is only required if this cannot be determined by calling each parameter node's usesGeometry() or
|
||||
* referencedColumns() method. For example, an aggregate expression requires the geometry and all columns
|
||||
* if the parent variable is used.
|
||||
* If a nullptr is passed as a node to these functions, they should stay on the safe side and return if they
|
||||
* could potentially require a geometry or columns.
|
||||
*/
|
||||
QgsStaticExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
FcnEval fcn,
|
||||
const QString &group,
|
||||
const QString &helpText,
|
||||
std::function < bool ( const QgsExpressionNodeFunction *node ) > usesGeometry,
|
||||
std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > referencedColumns,
|
||||
bool lazyEval = false,
|
||||
const QStringList &aliases = QStringList(),
|
||||
bool handlesNull = false );
|
||||
|
||||
|
||||
/** Static function for evaluation against a QgsExpressionContext, using a named list of parameter values and list
|
||||
* of groups.
|
||||
*/
|
||||
QgsStaticExpressionFunction( const QString &fnname,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
FcnEval fcn,
|
||||
const QStringList &groups,
|
||||
const QString &helpText = QString(),
|
||||
bool usesGeometry = false,
|
||||
const QSet<QString> &referencedColumns = QSet<QString>(),
|
||||
bool lazyEval = false,
|
||||
const QStringList &aliases = QStringList(),
|
||||
bool handlesNull = false )
|
||||
: QgsExpressionFunction( fnname, params, groups, helpText, lazyEval, handlesNull )
|
||||
, mFnc( fcn )
|
||||
, mAliases( aliases )
|
||||
, mUsesGeometry( usesGeometry )
|
||||
, mReferencedColumns( referencedColumns )
|
||||
{}
|
||||
|
||||
/** Returns result of evaluating the function.
|
||||
* \param values list of values passed to the function
|
||||
* \param context context expression is being evaluated against
|
||||
* \param parent parent expression
|
||||
* \returns result of function
|
||||
*/
|
||||
virtual QVariant func( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) override
|
||||
{
|
||||
return mFnc ? mFnc( values, context, parent ) : QVariant();
|
||||
}
|
||||
|
||||
virtual QStringList aliases() const override;
|
||||
|
||||
virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
|
||||
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
virtual bool prepare( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
/**
|
||||
* Set a function that will be called in the prepare step to determine if the function is
|
||||
* static or not.
|
||||
* By default this is set to a function that checks all arguments that have been passed to the variable
|
||||
* and if all of them are static, it will be assumed that the function is static as well.
|
||||
*/
|
||||
void setIsStaticFunction( std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > isStatic );
|
||||
|
||||
/**
|
||||
* Tag this function as either static or not static.
|
||||
* This will indicate that the function is always expected to return the same value for
|
||||
* an iteration (or explicitly request that it's going to be called for every feature, if false).
|
||||
*
|
||||
* \see setIsStaticFunction
|
||||
*/
|
||||
void setIsStatic( bool isStatic );
|
||||
|
||||
/**
|
||||
* Set a function that will be called in the prepare step to determine if the function is
|
||||
* static or not.
|
||||
* By default this is set to a function that checks all arguments that have been passed to the variable
|
||||
* and if all of them are static, it will be assumed that the function is static as well.
|
||||
*/
|
||||
void setPrepareFunction( std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > prepareFunc );
|
||||
|
||||
|
||||
private:
|
||||
FcnEval mFnc;
|
||||
QStringList mAliases;
|
||||
bool mUsesGeometry;
|
||||
std::function < bool( const QgsExpressionNodeFunction *node ) > mUsesGeometryFunc;
|
||||
std::function < QSet<QString>( const QgsExpressionNodeFunction *node ) > mReferencedColumnsFunc;
|
||||
std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mIsStaticFunc = allParamsStatic;
|
||||
std::function < bool( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) > mPrepareFunc;
|
||||
QSet<QString> mReferencedColumns;
|
||||
bool mIsStatic = false;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // QGSEXPRESSIONFUNCTION_H
|
1
src/core/expression/qgsexpressionnode.cpp
Normal file
1
src/core/expression/qgsexpressionnode.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "qgsexpressionnode.h"
|
259
src/core/expression/qgsexpressionnode.h
Normal file
259
src/core/expression/qgsexpressionnode.h
Normal file
@ -0,0 +1,259 @@
|
||||
#ifndef QGSEXPRESSIONNODE_H
|
||||
#define QGSEXPRESSIONNODE_H
|
||||
|
||||
#include <QSet>
|
||||
#include <QVariant>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "qgis.h"
|
||||
|
||||
class QgsExpression;
|
||||
class QgsExpressionContext;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
*
|
||||
* Abstract base class for all nodes that can appear in an expression.
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNode SIP_ABSTRACT
|
||||
{
|
||||
|
||||
#ifdef SIP_RUN
|
||||
SIP_CONVERT_TO_SUBCLASS_CODE
|
||||
switch ( sipCpp->nodeType() )
|
||||
{
|
||||
case QgsExpressionNode::ntUnaryOperator:
|
||||
sipType = sipType_QgsExpressionNodeUnaryOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntBinaryOperator:
|
||||
sipType = sipType_QgsExpressionNodeBinaryOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntInOperator:
|
||||
sipType = sipType_QgsExpressionNodeInOperator;
|
||||
break;
|
||||
case QgsExpressionNode::ntFunction:
|
||||
sipType = sipType_QgsExpressionNodeFunction;
|
||||
break;
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
sipType = sipType_QgsExpressionNodeLiteral;
|
||||
break;
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
sipType = sipType_QgsExpressionNodeColumnRef;
|
||||
break;
|
||||
case QgsExpressionNode::ntCondition:
|
||||
sipType = sipType_QgsExpressionNodeCondition;
|
||||
break;
|
||||
default:
|
||||
sipType = 0;
|
||||
break;
|
||||
}
|
||||
SIP_END
|
||||
#endif
|
||||
|
||||
Q_DECLARE_TR_FUNCTIONS( QgsExpressionNode );
|
||||
|
||||
public:
|
||||
enum NodeType
|
||||
{
|
||||
ntUnaryOperator, //!< \see QgsExpression::Node::NodeUnaryOperator
|
||||
ntBinaryOperator, //!< \see QgsExpression::Node::NodeBinaryOperator
|
||||
ntInOperator, //!< \see QgsExpression::Node::NodeInOperator
|
||||
ntFunction, //!< \see QgsExpression::Node::NodeFunction
|
||||
ntLiteral, //!< \see QgsExpression::Node::NodeLiteral
|
||||
ntColumnRef, //!< \see QgsExpression::Node::NodeColumnRef
|
||||
ntCondition //!< \see QgsExpression::Node::NodeCondition
|
||||
};
|
||||
|
||||
|
||||
//! Named node
|
||||
//! \since QGIS 2.16
|
||||
//! \ingroup core
|
||||
struct NamedNode
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructor for NamedNode
|
||||
* \param name node name
|
||||
* \param node node
|
||||
*/
|
||||
NamedNode( const QString &name, QgsExpressionNode *node )
|
||||
: name( name )
|
||||
, node( node )
|
||||
{}
|
||||
|
||||
//! Node name
|
||||
QString name;
|
||||
|
||||
//! Node
|
||||
QgsExpressionNode *node = nullptr;
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class NodeList
|
||||
{
|
||||
public:
|
||||
virtual ~NodeList();
|
||||
//! Takes ownership of the provided node
|
||||
void append( QgsExpressionNode *node SIP_TRANSFER ) { mList.append( node ); mNameList.append( QString() ); }
|
||||
|
||||
/** Adds a named node. Takes ownership of the provided node.
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
void append( QgsExpressionNode::NamedNode *node SIP_TRANSFER );
|
||||
|
||||
/** Returns the number of nodes in the list.
|
||||
*/
|
||||
int count() const { return mList.count(); }
|
||||
|
||||
//! Returns true if list contains any named nodes
|
||||
//! \since QGIS 2.16
|
||||
bool hasNamedNodes() const { return mHasNamedNodes; }
|
||||
|
||||
/**
|
||||
* Get a list of all the nodes.
|
||||
*/
|
||||
QList<QgsExpressionNode *> list() { return mList; }
|
||||
|
||||
/**
|
||||
* Get the node at position i in the list.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsExpressionNode *at( int i ) { return mList.at( i ); }
|
||||
|
||||
//! Returns a list of names for nodes. Unnamed nodes will be indicated by an empty string in the list.
|
||||
//! \since QGIS 2.16
|
||||
QStringList names() const { return mNameList; }
|
||||
|
||||
//! Creates a deep copy of this list. Ownership is transferred to the caller
|
||||
NodeList *clone() const;
|
||||
|
||||
virtual QString dump() const;
|
||||
|
||||
private:
|
||||
QList<QgsExpressionNode *> mList;
|
||||
QStringList mNameList;
|
||||
|
||||
bool mHasNamedNodes = false;
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
virtual ~QgsExpressionNode() = default;
|
||||
|
||||
/**
|
||||
* Get the type of this node.
|
||||
*
|
||||
* \returns The type of this node
|
||||
*/
|
||||
virtual QgsExpressionNode::NodeType nodeType() const = 0;
|
||||
|
||||
/**
|
||||
* Dump this node into a serialized (part) of an expression.
|
||||
* The returned expression does not necessarily literally match
|
||||
* the original expression, it's just guaranteed to behave the same way.
|
||||
*/
|
||||
virtual QString dump() const = 0;
|
||||
|
||||
/**
|
||||
* Evaluate this node with the given context and parent.
|
||||
* This will return a cached value if it has been determined to be static
|
||||
* during the prepare() execution.
|
||||
*
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
QVariant eval( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
|
||||
/**
|
||||
* Generate a clone of this node.
|
||||
* Ownership is transferred to the caller.
|
||||
*
|
||||
* \returns a deep copy of this node.
|
||||
*/
|
||||
virtual QgsExpressionNode *clone() const = 0;
|
||||
|
||||
/**
|
||||
* Abstract virtual method which returns a list of columns required to
|
||||
* evaluate this node.
|
||||
*
|
||||
* When reimplementing this, you need to return any column that is required to
|
||||
* evaluate this node and in addition recursively collect all the columns required
|
||||
* to evaluate child nodes.
|
||||
*
|
||||
* \returns A list of columns required to evaluate this expression
|
||||
*/
|
||||
virtual QSet<QString> referencedColumns() const = 0;
|
||||
|
||||
/**
|
||||
* Return a set of all variables which are used in this expression.
|
||||
*/
|
||||
virtual QSet<QString> referencedVariables() const = 0;
|
||||
|
||||
/**
|
||||
* Abstract virtual method which returns if the geometry is required to evaluate
|
||||
* this expression.
|
||||
*
|
||||
* This needs to call `needsGeometry()` recursively on any child nodes.
|
||||
*
|
||||
* \returns true if a geometry is required to evaluate this expression
|
||||
*/
|
||||
virtual bool needsGeometry() const = 0;
|
||||
|
||||
/**
|
||||
* Returns true if this node can be evaluated for a static value. This is used during
|
||||
* the prepare() step and in case it returns true, the value of this node will already
|
||||
* be evaluated and the result cached (and therefore not re-evaluated in subsequent calls
|
||||
* to eval()). In case this returns true, prepareNode() will never be called.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const = 0;
|
||||
|
||||
/**
|
||||
* Prepare this node for evaluation.
|
||||
* This will check if the node content is static and in this case cache the value.
|
||||
* If it's not static it will call prepareNode() to allow the node to do initialization
|
||||
* work like for example resolving a column name to an attribute index.
|
||||
*
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
bool prepare( QgsExpression *parent, const QgsExpressionContext *context );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Copies the members of this node to the node provided in \a target.
|
||||
* Needs to be called by all subclasses as part of their clone() implementation.
|
||||
*
|
||||
* \note Not available in python bindings, QgsExpression::Node is not
|
||||
* going to be subclassed from python. If that's what you are looking
|
||||
* for, look into writing a custom python expression function.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void cloneTo( QgsExpressionNode *target ) const SIP_SKIP;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Abstract virtual preparation method
|
||||
* Errors are reported to the parent
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) = 0;
|
||||
|
||||
/**
|
||||
* Abstract virtual eval method
|
||||
* Errors are reported to the parent
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) = 0;
|
||||
|
||||
bool mHasCachedValue = false;
|
||||
QVariant mCachedStaticValue;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE( QgsExpressionNode * )
|
||||
|
||||
#endif // QGSEXPRESSIONNODE_H
|
6
src/core/expression/qgsexpressionnodeimpl.cpp
Normal file
6
src/core/expression/qgsexpressionnodeimpl.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
QString QgsExpressionNodeBinaryOperator::text() const
|
||||
{
|
||||
return BINARY_OPERATOR_TEXT[mOp];
|
||||
}
|
356
src/core/expression/qgsexpressionnodeimpl.h
Normal file
356
src/core/expression/qgsexpressionnodeimpl.h
Normal file
@ -0,0 +1,356 @@
|
||||
#ifndef QGSEXPRESSIONNODEIMPL_H
|
||||
#define QGSEXPRESSIONNODEIMPL_H
|
||||
|
||||
#include "qgsexpressionnode.h"
|
||||
#include "qgsinterval.h"
|
||||
|
||||
/** \ingroup core
|
||||
* A unary node is either negative as in boolean (not) or as in numbers (minus).
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeUnaryOperator : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief list of unary operators
|
||||
* \note if any change is made here, the definition of QgsExpression::UnaryOperatorText[] must be adapted.
|
||||
*/
|
||||
enum UnaryOperator
|
||||
{
|
||||
uoNot,
|
||||
uoMinus,
|
||||
};
|
||||
|
||||
/**
|
||||
* A node unary operator is modifying the value of \a operand by negating it with \a op.
|
||||
*/
|
||||
QgsExpressionNodeUnaryOperator( QgsExpressionNodeUnaryOperator::UnaryOperator op, QgsExpressionNode *operand SIP_TRANSFER )
|
||||
: mOp( op )
|
||||
, mOperand( operand )
|
||||
{}
|
||||
~QgsExpressionNodeUnaryOperator() { delete mOperand; }
|
||||
|
||||
QgsExpressionNodeUnaryOperator::UnaryOperator op() const { return mOp; }
|
||||
QgsExpressionNode *operand() const { return mOperand; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
/**
|
||||
* Returns a the name of this operator without the operands.
|
||||
* I.e. "NOT" or "-"
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
private:
|
||||
UnaryOperator mOp;
|
||||
QgsExpressionNode *mOperand = nullptr;
|
||||
|
||||
static const char *UNARY_OPERATOR_TEXT[];
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeBinaryOperator : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief list of binary operators
|
||||
* \note if any change is made here, the definition of QgsExpression::BinaryOperatorText[] must be adapted.
|
||||
*/
|
||||
enum BinaryOperator
|
||||
{
|
||||
// logical
|
||||
boOr,
|
||||
boAnd,
|
||||
|
||||
// comparison
|
||||
boEQ, //!< =
|
||||
boNE, //!< <>
|
||||
boLE, //!< <=
|
||||
boGE, //!< >=
|
||||
boLT, //!< <
|
||||
boGT, //!< >
|
||||
boRegexp,
|
||||
boLike,
|
||||
boNotLike,
|
||||
boILike,
|
||||
boNotILike,
|
||||
boIs,
|
||||
boIsNot,
|
||||
|
||||
// math
|
||||
boPlus,
|
||||
boMinus,
|
||||
boMul,
|
||||
boDiv,
|
||||
boIntDiv,
|
||||
boMod,
|
||||
boPow,
|
||||
|
||||
// strings
|
||||
boConcat,
|
||||
};
|
||||
|
||||
/**
|
||||
* Binary combination of the left and the right with op.
|
||||
*/
|
||||
QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::BinaryOperator op, QgsExpressionNode *opLeft SIP_TRANSFER, QgsExpressionNode *opRight SIP_TRANSFER )
|
||||
: mOp( op )
|
||||
, mOpLeft( opLeft )
|
||||
, mOpRight( opRight )
|
||||
{}
|
||||
~QgsExpressionNodeBinaryOperator() { delete mOpLeft; delete mOpRight; }
|
||||
|
||||
QgsExpressionNodeBinaryOperator::BinaryOperator op() const { return mOp; }
|
||||
QgsExpressionNode *opLeft() const { return mOpLeft; }
|
||||
QgsExpressionNode *opRight() const { return mOpRight; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
int precedence() const;
|
||||
bool leftAssociative() const;
|
||||
|
||||
/**
|
||||
* Returns a the name of this operator without the operands.
|
||||
* I.e. "AND", "OR", ...
|
||||
*/
|
||||
QString text() const;
|
||||
|
||||
private:
|
||||
bool compare( double diff );
|
||||
qlonglong computeInt( qlonglong x, qlonglong y );
|
||||
double computeDouble( double x, double y );
|
||||
|
||||
/** Computes the result date time calculation from a start datetime and an interval
|
||||
* \param d start datetime
|
||||
* \param i interval to add or subtract (depending on mOp)
|
||||
*/
|
||||
QDateTime computeDateTimeFromInterval( const QDateTime &d, QgsInterval *i );
|
||||
|
||||
BinaryOperator mOp;
|
||||
QgsExpressionNode *mOpLeft = nullptr;
|
||||
QgsExpressionNode *mOpRight = nullptr;
|
||||
|
||||
static const char *BINARY_OPERATOR_TEXT[];
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeInOperator : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* This node tests if the result of \a node is in the result of \a list. Optionally it can be inverted with \a notin which by default is false.
|
||||
*/
|
||||
QgsExpressionNodeInOperator( QgsExpressionNode *node SIP_TRANSFER, QgsExpressionNode::NodeList *list SIP_TRANSFER, bool notin = false )
|
||||
: mNode( node )
|
||||
, mList( list )
|
||||
, mNotIn( notin )
|
||||
{}
|
||||
virtual ~QgsExpressionNodeInOperator();
|
||||
|
||||
QgsExpressionNode *node() const { return mNode; }
|
||||
bool isNotIn() const { return mNotIn; }
|
||||
QgsExpressionNode::NodeList *list() const { return mList; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
private:
|
||||
QgsExpressionNode *mNode = nullptr;
|
||||
QgsExpressionNodeInOperator::NodeList *mList = nullptr;
|
||||
bool mNotIn;
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeFunction : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* A function node consists of an index of the function in the global function array and
|
||||
* a list of arguments that will be passed to it.
|
||||
*/
|
||||
QgsExpressionNodeFunction( int fnIndex, QgsExpressionNode::NodeList *args SIP_TRANSFER );
|
||||
|
||||
virtual ~QgsExpressionNodeFunction();
|
||||
|
||||
int fnIndex() const { return mFnIndex; }
|
||||
QgsExpressionNode::NodeList *args() const { return mArgs; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
//! Tests whether the provided argument list is valid for the matching function
|
||||
static bool validateParams( int fnIndex, QgsExpressionNode::NodeList *args, QString &error );
|
||||
|
||||
private:
|
||||
int mFnIndex;
|
||||
NodeList *mArgs = nullptr;
|
||||
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeLiteral : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
QgsExpressionNodeLiteral( const QVariant &value )
|
||||
: mValue( value )
|
||||
{}
|
||||
|
||||
//! The value of the literal.
|
||||
inline QVariant value() const { return mValue; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
private:
|
||||
QVariant mValue;
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeColumnRef : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
QgsExpressionNodeColumnRef( const QString &name )
|
||||
: mName( name )
|
||||
, mIndex( -1 )
|
||||
{}
|
||||
|
||||
//! The name of the column.
|
||||
QString name() const { return mName; }
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
private:
|
||||
QString mName;
|
||||
int mIndex;
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
*/
|
||||
class CORE_EXPORT QgsExpressionNodeCondition : public QgsExpressionNode
|
||||
{
|
||||
public:
|
||||
class CORE_EXPORT WhenThen
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* A combination of when and then. Simple as that.
|
||||
*/
|
||||
WhenThen( QgsExpressionNode *whenExp, QgsExpressionNode *thenExp );
|
||||
~WhenThen();
|
||||
|
||||
//! WhenThen nodes cannot be copied.
|
||||
WhenThen( const WhenThen &rh ) = delete;
|
||||
//! WhenThen nodes cannot be copied.
|
||||
WhenThen &operator=( const WhenThen &rh ) = delete;
|
||||
|
||||
/**
|
||||
* Get a deep copy of this WhenThen combination.
|
||||
*/
|
||||
QgsExpressionNodeCondition::WhenThen *clone() const;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
WhenThen( const QgsExpressionNodeCondition::WhenThen &rh );
|
||||
#endif
|
||||
QgsExpressionNode *mWhenExp = nullptr;
|
||||
QgsExpressionNode *mThenExp = nullptr;
|
||||
|
||||
friend class QgsExpressionNodeCondition;
|
||||
};
|
||||
typedef QList<QgsExpressionNodeCondition::WhenThen *> WhenThenList;
|
||||
|
||||
/**
|
||||
* Create a new node with the given list of \a conditions and an optional \a elseExp expression.
|
||||
*/
|
||||
QgsExpressionNodeCondition( QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp = nullptr );
|
||||
|
||||
/**
|
||||
* Create a new node with the given list of \a conditions and an optional \a elseExp expression.
|
||||
*/
|
||||
QgsExpressionNodeCondition( const QgsExpressionNodeCondition::WhenThenList &conditions, QgsExpressionNode *elseExp = nullptr ) SIP_SKIP
|
||||
: mConditions( conditions )
|
||||
, mElseExp( elseExp )
|
||||
{}
|
||||
|
||||
~QgsExpressionNodeCondition();
|
||||
|
||||
virtual QgsExpressionNode::NodeType nodeType() const override;
|
||||
virtual QVariant evalNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual bool prepareNode( QgsExpression *parent, const QgsExpressionContext *context ) override;
|
||||
virtual QString dump() const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns() const override;
|
||||
virtual QSet<QString> referencedVariables() const override;
|
||||
virtual bool needsGeometry() const override;
|
||||
virtual QgsExpressionNode *clone() const override;
|
||||
virtual bool isStatic( QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
private:
|
||||
WhenThenList mConditions;
|
||||
QgsExpressionNode *mElseExp = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSEXPRESSIONNODEIMPL_H
|
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,7 @@
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
#include "qgsfields.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsproject.h"
|
||||
@ -190,7 +191,7 @@ bool QgsExpressionContextScope::hasFunction( const QString &name ) const
|
||||
return mFunctions.contains( name );
|
||||
}
|
||||
|
||||
QgsExpression::Function *QgsExpressionContextScope::function( const QString &name ) const
|
||||
QgsExpressionFunction *QgsExpressionContextScope::function( const QString &name ) const
|
||||
{
|
||||
return mFunctions.contains( name ) ? mFunctions.value( name ) : nullptr;
|
||||
}
|
||||
@ -423,7 +424,7 @@ QStringList QgsExpressionContext::functionNames() const
|
||||
return result;
|
||||
}
|
||||
|
||||
QgsExpression::Function *QgsExpressionContext::function( const QString &name ) const
|
||||
QgsExpressionFunction *QgsExpressionContext::function( const QString &name ) const
|
||||
{
|
||||
//iterate through stack backwards, so that higher priority variables take precedence
|
||||
QList< QgsExpressionContextScope * >::const_iterator it = mStack.constEnd();
|
||||
@ -638,7 +639,7 @@ class GetComposerItemVariables : public QgsScopedExpressionFunction
|
||||
{
|
||||
public:
|
||||
GetComposerItemVariables( const QgsComposition *c )
|
||||
: QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpression::ParameterList() << QgsExpression::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Composition" ) )
|
||||
: QgsScopedExpressionFunction( QStringLiteral( "item_variables" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "Composition" ) )
|
||||
, mComposition( c )
|
||||
{}
|
||||
|
||||
@ -673,7 +674,7 @@ class GetLayerVisibility : public QgsScopedExpressionFunction
|
||||
{
|
||||
public:
|
||||
GetLayerVisibility( const QList<QgsMapLayer *> &layers )
|
||||
: QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpression::ParameterList() << QgsExpression::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
|
||||
: QgsScopedExpressionFunction( QStringLiteral( "is_layer_visible" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "id" ) ), QStringLiteral( "General" ) )
|
||||
, mLayers( layers )
|
||||
{}
|
||||
|
||||
@ -1081,19 +1082,19 @@ void QgsExpressionContextUtils::registerContextFunctions()
|
||||
QgsExpression::registerFunction( new GetLayerVisibility( QList<QgsMapLayer *>() ) );
|
||||
}
|
||||
|
||||
bool QgsScopedExpressionFunction::usesGeometry( const QgsExpression::NodeFunction *node ) const
|
||||
bool QgsScopedExpressionFunction::usesGeometry( const QgsExpressionNodeFunction *node ) const
|
||||
{
|
||||
Q_UNUSED( node )
|
||||
return mUsesGeometry;
|
||||
}
|
||||
|
||||
QSet<QString> QgsScopedExpressionFunction::referencedColumns( const QgsExpression::NodeFunction *node ) const
|
||||
QSet<QString> QgsScopedExpressionFunction::referencedColumns( const QgsExpressionNodeFunction *node ) const
|
||||
{
|
||||
Q_UNUSED( node )
|
||||
return mReferencedColumns;
|
||||
}
|
||||
|
||||
bool QgsScopedExpressionFunction::isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
|
||||
bool QgsScopedExpressionFunction::isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const
|
||||
{
|
||||
return allParamsStatic( node, parent, context );
|
||||
}
|
||||
|
@ -25,8 +25,10 @@
|
||||
#include <QSet>
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
|
||||
class QgsExpression;
|
||||
class QgsExpressionNodeFunction;
|
||||
class QgsMapLayer;
|
||||
class QgsComposition;
|
||||
class QgsComposerItem;
|
||||
@ -43,7 +45,7 @@ class QgsSymbol;
|
||||
* \since QGIS 2.12
|
||||
*/
|
||||
|
||||
class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
|
||||
class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpressionFunction
|
||||
{
|
||||
public:
|
||||
|
||||
@ -61,7 +63,7 @@ class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = true )
|
||||
: QgsExpression::Function( fnname, params, group, helpText, lazyEval, handlesNull, isContextual )
|
||||
: QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull, isContextual )
|
||||
, mUsesGeometry( usesGeometry )
|
||||
, mReferencedColumns( referencedColumns )
|
||||
{}
|
||||
@ -72,7 +74,7 @@ class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
QgsScopedExpressionFunction( const QString &fnname,
|
||||
const QgsExpression::ParameterList ¶ms,
|
||||
const QgsExpressionFunction::ParameterList ¶ms,
|
||||
const QString &group,
|
||||
const QString &helpText = QString(),
|
||||
bool usesGeometry = false,
|
||||
@ -80,7 +82,7 @@ class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
|
||||
bool lazyEval = false,
|
||||
bool handlesNull = false,
|
||||
bool isContextual = true )
|
||||
: QgsExpression::Function( fnname, params, group, helpText, lazyEval, handlesNull, isContextual )
|
||||
: QgsExpressionFunction( fnname, params, group, helpText, lazyEval, handlesNull, isContextual )
|
||||
, mUsesGeometry( usesGeometry )
|
||||
, mReferencedColumns( referencedColumns )
|
||||
{}
|
||||
@ -91,11 +93,11 @@ class CORE_EXPORT QgsScopedExpressionFunction : public QgsExpression::Function
|
||||
*/
|
||||
virtual QgsScopedExpressionFunction *clone() const = 0 SIP_FACTORY;
|
||||
|
||||
virtual bool usesGeometry( const QgsExpression::NodeFunction *node ) const override;
|
||||
virtual bool usesGeometry( const QgsExpressionNodeFunction *node ) const override;
|
||||
|
||||
virtual QSet<QString> referencedColumns( const QgsExpression::NodeFunction *node ) const override;
|
||||
virtual QSet<QString> referencedColumns( const QgsExpressionNodeFunction *node ) const override;
|
||||
|
||||
virtual bool isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override;
|
||||
|
||||
private:
|
||||
bool mUsesGeometry;
|
||||
@ -253,7 +255,7 @@ class CORE_EXPORT QgsExpressionContextScope
|
||||
* \see functionNames()
|
||||
* \see variable()
|
||||
*/
|
||||
QgsExpression::Function *function( const QString &name ) const;
|
||||
QgsExpressionFunction *function( const QString &name ) const;
|
||||
|
||||
/** Retrieves a list of names of functions contained in the scope.
|
||||
* \see function()
|
||||
@ -479,7 +481,7 @@ class CORE_EXPORT QgsExpressionContext
|
||||
* \returns function if contained by the context, otherwise null.
|
||||
* \see hasFunction
|
||||
*/
|
||||
QgsExpression::Function *function( const QString &name ) const;
|
||||
QgsExpressionFunction *function( const QString &name ) const;
|
||||
|
||||
/** Returns the number of scopes contained in the context.
|
||||
*/
|
||||
|
@ -31,7 +31,9 @@
|
||||
#include <stdlib.h> // atof()
|
||||
|
||||
#include "qgsexpression.h"
|
||||
struct expression_parser_context;
|
||||
#include "expression/qgsexpressionnodeimpl.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
struct expression_parser_context;
|
||||
#include "qgsexpressionparser.hpp"
|
||||
#include <QLocale>
|
||||
|
||||
@ -47,8 +49,8 @@ struct expression_parser_context;
|
||||
#define YY_NO_UNISTD_H
|
||||
#endif
|
||||
|
||||
#define B_OP(x) yylval->b_op = QgsExpression::x
|
||||
#define U_OP(x) yylval->u_op = QgsExpression::x
|
||||
#define B_OP(x) yylval->b_op = QgsExpressionNodeBinaryOperator::x
|
||||
#define U_OP(x) yylval->u_op = QgsExpressionNodeUnaryOperator::x
|
||||
#define TEXT yylval->text = new QString( QString::fromUtf8(yytext) );
|
||||
#define TEXT_FILTER(filter_fn) yylval->text = new QString( filter_fn( QString::fromUtf8(yytext) ) );
|
||||
|
||||
|
@ -17,7 +17,10 @@
|
||||
#include <qglobal.h>
|
||||
#include <QList>
|
||||
#include <cstdlib>
|
||||
#include "qgsexpression.h"
|
||||
#include "expression/qgsexpression.h"
|
||||
#include "expression/qgsexpressionnode.h"
|
||||
#include "expression/qgsexpressionnodeimpl.h"
|
||||
#include "expression/qgsexpressionfunction.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable: 4065 ) // switch statement contains 'default' but no 'case' labels
|
||||
@ -41,7 +44,7 @@ extern YY_BUFFER_STATE exp__scan_string(const char* buffer, yyscan_t scanner);
|
||||
/** returns parsed tree, otherwise returns nullptr and sets parserErrorMsg
|
||||
(interface function to be called from QgsExpression)
|
||||
*/
|
||||
QgsExpression::Node* parseExpression(const QString& str, QString& parserErrorMsg);
|
||||
QgsExpressionNode* parseExpression(const QString& str, QString& parserErrorMsg);
|
||||
|
||||
/** error handler for bison */
|
||||
void exp_error(expression_parser_context* parser_ctx, const char* msg);
|
||||
@ -54,7 +57,7 @@ struct expression_parser_context
|
||||
// varible where the parser error will be stored
|
||||
QString errorMsg;
|
||||
// root node of the expression
|
||||
QgsExpression::Node* rootNode;
|
||||
QgsExpressionNode* rootNode;
|
||||
};
|
||||
|
||||
#define scanner parser_ctx->flex_scanner
|
||||
@ -62,7 +65,7 @@ struct expression_parser_context
|
||||
// we want verbose error messages
|
||||
#define YYERROR_VERBOSE 1
|
||||
|
||||
#define BINOP(x, y, z) new QgsExpression::NodeBinaryOperator(x, y, z)
|
||||
#define BINOP(x, y, z) new QgsExpressionNodeBinaryOperator(x, y, z)
|
||||
|
||||
%}
|
||||
|
||||
@ -75,17 +78,17 @@ struct expression_parser_context
|
||||
|
||||
%union
|
||||
{
|
||||
QgsExpression::Node* node;
|
||||
QgsExpression::NodeList* nodelist;
|
||||
QgsExpression::NamedNode* namednode;
|
||||
QgsExpressionNode* node;
|
||||
QgsExpressionNode::NodeList* nodelist;
|
||||
QgsExpressionNode::NamedNode* namednode;
|
||||
double numberFloat;
|
||||
int numberInt;
|
||||
bool boolVal;
|
||||
QString* text;
|
||||
QgsExpression::BinaryOperator b_op;
|
||||
QgsExpression::UnaryOperator u_op;
|
||||
QgsExpression::WhenThen* whenthen;
|
||||
QgsExpression::WhenThenList* whenthenlist;
|
||||
QgsExpressionNodeBinaryOperator::BinaryOperator b_op;
|
||||
QgsExpressionNodeUnaryOperator::UnaryOperator u_op;
|
||||
QgsExpressionNodeCondition::WhenThen* whenthen;
|
||||
QgsExpressionNodeCondition::WhenThenList* whenthenlist;
|
||||
}
|
||||
|
||||
%start root
|
||||
@ -180,7 +183,7 @@ expression:
|
||||
| expression MOD expression { $$ = BINOP($2, $1, $3); }
|
||||
| expression POW expression { $$ = BINOP($2, $1, $3); }
|
||||
| expression CONCAT expression { $$ = BINOP($2, $1, $3); }
|
||||
| NOT expression { $$ = new QgsExpression::NodeUnaryOperator($1, $2); }
|
||||
| NOT expression { $$ = new QgsExpressionNodeUnaryOperator($1, $2); }
|
||||
| '(' expression ')' { $$ = $2; }
|
||||
| FUNCTION '(' exp_list ')'
|
||||
{
|
||||
@ -195,7 +198,7 @@ expression:
|
||||
YYERROR;
|
||||
}
|
||||
QString paramError;
|
||||
if ( !QgsExpression::NodeFunction::validateParams( fnIndex, $3, paramError ) )
|
||||
if ( !QgsExpressionNodeFunction::validateParams( fnIndex, $3, paramError ) )
|
||||
{
|
||||
exp_error( parser_ctx, paramError.toLocal8Bit().constData() );
|
||||
delete $3;
|
||||
@ -209,7 +212,7 @@ expression:
|
||||
delete $3;
|
||||
YYERROR;
|
||||
}
|
||||
$$ = new QgsExpression::NodeFunction(fnIndex, $3);
|
||||
$$ = new QgsExpressionNodeFunction(fnIndex, $3);
|
||||
}
|
||||
|
||||
| FUNCTION '(' ')'
|
||||
@ -230,20 +233,20 @@ expression:
|
||||
exp_error(parser_ctx, QString( "%1 function is called with wrong number of arguments" ).arg( QgsExpression::Functions()[fnIndex]->name() ).toLocal8Bit().constData() );
|
||||
YYERROR;
|
||||
}
|
||||
$$ = new QgsExpression::NodeFunction(fnIndex, new QgsExpression::NodeList());
|
||||
$$ = new QgsExpressionNodeFunction(fnIndex, new QgsExpressionNode::NodeList());
|
||||
}
|
||||
|
||||
| expression IN '(' exp_list ')' { $$ = new QgsExpression::NodeInOperator($1, $4, false); }
|
||||
| expression NOT IN '(' exp_list ')' { $$ = new QgsExpression::NodeInOperator($1, $5, true); }
|
||||
| expression IN '(' exp_list ')' { $$ = new QgsExpressionNodeInOperator($1, $4, false); }
|
||||
| expression NOT IN '(' exp_list ')' { $$ = new QgsExpressionNodeInOperator($1, $5, true); }
|
||||
|
||||
| PLUS expression %prec UMINUS { $$ = $2; }
|
||||
| MINUS expression %prec UMINUS { $$ = new QgsExpression::NodeUnaryOperator( QgsExpression::uoMinus, $2); }
|
||||
| MINUS expression %prec UMINUS { $$ = new QgsExpressionNodeUnaryOperator( QgsExpressionNodeUnaryOperator::uoMinus, $2); }
|
||||
|
||||
| CASE when_then_clauses END { $$ = new QgsExpression::NodeCondition($2); }
|
||||
| CASE when_then_clauses ELSE expression END { $$ = new QgsExpression::NodeCondition($2,$4); }
|
||||
| CASE when_then_clauses END { $$ = new QgsExpressionNodeCondition($2); }
|
||||
| CASE when_then_clauses ELSE expression END { $$ = new QgsExpressionNodeCondition($2,$4); }
|
||||
|
||||
// columns
|
||||
| COLUMN_REF { $$ = new QgsExpression::NodeColumnRef( *$1 ); delete $1; }
|
||||
| COLUMN_REF { $$ = new QgsExpressionNodeColumnRef( *$1 ); delete $1; }
|
||||
|
||||
// special columns (actually functions with no arguments)
|
||||
| SPECIAL_COL
|
||||
@ -251,7 +254,7 @@ expression:
|
||||
int fnIndex = QgsExpression::functionIndex(*$1);
|
||||
if (fnIndex >= 0)
|
||||
{
|
||||
$$ = new QgsExpression::NodeFunction( fnIndex, nullptr );
|
||||
$$ = new QgsExpressionNodeFunction( fnIndex, nullptr );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -265,23 +268,23 @@ expression:
|
||||
| VARIABLE
|
||||
{
|
||||
// @var is equivalent to var( "var" )
|
||||
QgsExpression::NodeList* args = new QgsExpression::NodeList();
|
||||
QgsExpression::NodeLiteral* literal = new QgsExpression::NodeLiteral( QString(*$1).mid(1) );
|
||||
QgsExpressionNode::NodeList* args = new QgsExpressionNode::NodeList();
|
||||
QgsExpressionNodeLiteral* literal = new QgsExpressionNodeLiteral( QString(*$1).mid(1) );
|
||||
args->append( literal );
|
||||
$$ = new QgsExpression::NodeFunction( QgsExpression::functionIndex( "var" ), args );
|
||||
$$ = new QgsExpressionNodeFunction( QgsExpression::functionIndex( "var" ), args );
|
||||
delete $1;
|
||||
}
|
||||
|
||||
// literals
|
||||
| NUMBER_FLOAT { $$ = new QgsExpression::NodeLiteral( QVariant($1) ); }
|
||||
| NUMBER_INT { $$ = new QgsExpression::NodeLiteral( QVariant($1) ); }
|
||||
| BOOLEAN { $$ = new QgsExpression::NodeLiteral( QVariant($1) ); }
|
||||
| STRING { $$ = new QgsExpression::NodeLiteral( QVariant(*$1) ); delete $1; }
|
||||
| NULLVALUE { $$ = new QgsExpression::NodeLiteral( QVariant() ); }
|
||||
| NUMBER_FLOAT { $$ = new QgsExpressionNodeLiteral( QVariant($1) ); }
|
||||
| NUMBER_INT { $$ = new QgsExpressionNodeLiteral( QVariant($1) ); }
|
||||
| BOOLEAN { $$ = new QgsExpressionNodeLiteral( QVariant($1) ); }
|
||||
| STRING { $$ = new QgsExpressionNodeLiteral( QVariant(*$1) ); delete $1; }
|
||||
| NULLVALUE { $$ = new QgsExpressionNodeLiteral( QVariant() ); }
|
||||
;
|
||||
|
||||
named_node:
|
||||
NAMED_NODE expression { $$ = new QgsExpression::NamedNode( *$1, $2 ); delete $1; }
|
||||
NAMED_NODE expression { $$ = new QgsExpressionNode::NamedNode( *$1, $2 ); delete $1; }
|
||||
;
|
||||
|
||||
exp_list:
|
||||
@ -299,24 +302,24 @@ exp_list:
|
||||
}
|
||||
}
|
||||
| exp_list COMMA named_node { $$ = $1; $1->append($3); }
|
||||
| expression { $$ = new QgsExpression::NodeList(); $$->append($1); }
|
||||
| named_node { $$ = new QgsExpression::NodeList(); $$->append($1); }
|
||||
| expression { $$ = new QgsExpressionNode::NodeList(); $$->append($1); }
|
||||
| named_node { $$ = new QgsExpressionNode::NodeList(); $$->append($1); }
|
||||
;
|
||||
|
||||
when_then_clauses:
|
||||
when_then_clauses when_then_clause { $$ = $1; $1->append($2); }
|
||||
| when_then_clause { $$ = new QgsExpression::WhenThenList(); $$->append($1); }
|
||||
| when_then_clause { $$ = new QgsExpressionNodeCondition::WhenThenList(); $$->append($1); }
|
||||
;
|
||||
|
||||
when_then_clause:
|
||||
WHEN expression THEN expression { $$ = new QgsExpression::WhenThen($2,$4); }
|
||||
WHEN expression THEN expression { $$ = new QgsExpressionNodeCondition::WhenThen($2,$4); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
|
||||
// returns parsed tree, otherwise returns nullptr and sets parserErrorMsg
|
||||
QgsExpression::Node* parseExpression(const QString& str, QString& parserErrorMsg)
|
||||
QgsExpressionNode* parseExpression(const QString& str, QString& parserErrorMsg)
|
||||
{
|
||||
expression_parser_context ctx;
|
||||
ctx.rootNode = 0;
|
||||
|
@ -60,7 +60,7 @@ class QgsExpressionPrivate
|
||||
|
||||
QAtomicInt ref;
|
||||
|
||||
QgsExpression::Node *mRootNode = nullptr;
|
||||
QgsExpressionNode *mRootNode = nullptr;
|
||||
|
||||
QString mParserErrorString;
|
||||
QString mEvalErrorString;
|
||||
|
@ -141,18 +141,18 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
/**
|
||||
* Returns the layer's data provider.
|
||||
*/
|
||||
virtual QgsDataProvider *dataProvider() { return nullptr; }
|
||||
virtual QgsDataProvider *dataProvider();
|
||||
|
||||
/**
|
||||
* Returns the layer's data provider in a const-correct manner
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
virtual const QgsDataProvider *dataProvider() const SIP_SKIP { return nullptr; }
|
||||
virtual const QgsDataProvider *dataProvider() const SIP_SKIP;
|
||||
|
||||
/** Returns the original name of the layer.
|
||||
* \returns the original layer name
|
||||
*/
|
||||
QString originalName() const { return mLayerOrigName; }
|
||||
QString originalName() const;
|
||||
|
||||
/** Sets the short name of the layer
|
||||
* used by QGIS Server to identify the layer.
|
||||
@ -397,7 +397,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
/** Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated with it.
|
||||
* \since QGIS 2.16
|
||||
*/
|
||||
virtual bool isSpatial() const { return true; }
|
||||
virtual bool isSpatial() const;
|
||||
|
||||
/** Sets state from Dom document
|
||||
\param layerElement The Dom element corresponding to ``maplayer'' tag
|
||||
@ -465,7 +465,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
* for which layer cannot work and thus is not valid. It is not last error
|
||||
* after accessing data by draw() etc.
|
||||
*/
|
||||
virtual QgsError error() const { return mError; }
|
||||
virtual QgsError error() const;
|
||||
|
||||
/** Returns the layer's spatial reference system.
|
||||
\since QGIS 1.4
|
||||
@ -762,7 +762,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
* \see setMetadata()
|
||||
* \see metadataChanged()
|
||||
*/
|
||||
virtual const QgsLayerMetadata &metadata() const { return mMetadata; }
|
||||
virtual const QgsLayerMetadata &metadata() const;
|
||||
|
||||
/**
|
||||
* Sets the layer's \a metadata store.
|
||||
@ -779,7 +779,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
virtual QString htmlMetadata() const;
|
||||
|
||||
//! Time stamp of data source in the moment when data/metadata were loaded by provider
|
||||
virtual QDateTime timestamp() const { return QDateTime() ; }
|
||||
virtual QDateTime timestamp() const;
|
||||
|
||||
/**
|
||||
* Gets the list of dependencies. This includes data dependencies set by the user (\see setDataDependencies)
|
||||
@ -1032,7 +1032,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
|
||||
* This method returns true by default but can be overwritten to specify
|
||||
* that a certain layer is writable.
|
||||
*/
|
||||
virtual bool isReadOnly() const { return true; }
|
||||
virtual bool isReadOnly() const;
|
||||
|
||||
/** Layer's spatial reference system.
|
||||
private to make sure setCrs must be used and crsChanged() is emitted */
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "qgsogcutils.h"
|
||||
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
#include "qgsexpressionprivate.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgswkbptr.h"
|
||||
@ -1617,7 +1619,7 @@ QgsExpression *QgsOgcUtils::expressionFromOgcFilter( const QDomElement &element
|
||||
while ( !childElem.isNull() )
|
||||
{
|
||||
QString errorMsg;
|
||||
QgsExpression::Node *node = nodeFromOgcFilter( childElem, errorMsg );
|
||||
QgsExpressionNode *node = nodeFromOgcFilter( childElem, errorMsg );
|
||||
if ( !node )
|
||||
{
|
||||
// invalid expression, parser error
|
||||
@ -1632,7 +1634,7 @@ QgsExpression *QgsOgcUtils::expressionFromOgcFilter( const QDomElement &element
|
||||
}
|
||||
else
|
||||
{
|
||||
expr->d->mRootNode = new QgsExpression::NodeBinaryOperator( QgsExpression::boConcat, expr->d->mRootNode, node );
|
||||
expr->d->mRootNode = new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boConcat, expr->d->mRootNode, node );
|
||||
}
|
||||
|
||||
childElem = childElem.nextSiblingElement();
|
||||
@ -1648,21 +1650,21 @@ QgsExpression *QgsOgcUtils::expressionFromOgcFilter( const QDomElement &element
|
||||
static const QMap<QString, int> BINARY_OPERATORS_TAG_NAMES_MAP
|
||||
{
|
||||
// logical
|
||||
{ QStringLiteral( "Or" ), QgsExpression::boOr },
|
||||
{ QStringLiteral( "And" ), QgsExpression::boAnd },
|
||||
{ QStringLiteral( "Or" ), QgsExpressionNodeBinaryOperator::boOr },
|
||||
{ QStringLiteral( "And" ), QgsExpressionNodeBinaryOperator::boAnd },
|
||||
// comparison
|
||||
{ QStringLiteral( "PropertyIsEqualTo" ), QgsExpression::boEQ },
|
||||
{ QStringLiteral( "PropertyIsNotEqualTo" ), QgsExpression::boNE },
|
||||
{ QStringLiteral( "PropertyIsLessThanOrEqualTo" ), QgsExpression::boLE },
|
||||
{ QStringLiteral( "PropertyIsGreaterThanOrEqualTo" ), QgsExpression::boGE },
|
||||
{ QStringLiteral( "PropertyIsLessThan" ), QgsExpression::boLT },
|
||||
{ QStringLiteral( "PropertyIsGreaterThan" ), QgsExpression::boGT },
|
||||
{ QStringLiteral( "PropertyIsLike" ), QgsExpression::boLike },
|
||||
{ QStringLiteral( "PropertyIsEqualTo" ), QgsExpressionNodeBinaryOperator::boEQ },
|
||||
{ QStringLiteral( "PropertyIsNotEqualTo" ), QgsExpressionNodeBinaryOperator::boNE },
|
||||
{ QStringLiteral( "PropertyIsLessThanOrEqualTo" ), QgsExpressionNodeBinaryOperator::boLE },
|
||||
{ QStringLiteral( "PropertyIsGreaterThanOrEqualTo" ), QgsExpressionNodeBinaryOperator::boGE },
|
||||
{ QStringLiteral( "PropertyIsLessThan" ), QgsExpressionNodeBinaryOperator::boLT },
|
||||
{ QStringLiteral( "PropertyIsGreaterThan" ), QgsExpressionNodeBinaryOperator::boGT },
|
||||
{ QStringLiteral( "PropertyIsLike" ), QgsExpressionNodeBinaryOperator::boLike },
|
||||
// arithmetics
|
||||
{ QStringLiteral( "Add" ), QgsExpression::boPlus },
|
||||
{ QStringLiteral( "Sub" ), QgsExpression::boMinus },
|
||||
{ QStringLiteral( "Mul" ), QgsExpression::boMul },
|
||||
{ QStringLiteral( "Div" ), QgsExpression::boDiv },
|
||||
{ QStringLiteral( "Add" ), QgsExpressionNodeBinaryOperator::boPlus },
|
||||
{ QStringLiteral( "Sub" ), QgsExpressionNodeBinaryOperator::boMinus },
|
||||
{ QStringLiteral( "Mul" ), QgsExpressionNodeBinaryOperator::boMul },
|
||||
{ QStringLiteral( "Div" ), QgsExpressionNodeBinaryOperator::boDiv },
|
||||
};
|
||||
|
||||
static int binaryOperatorFromTagName( const QString &tagName )
|
||||
@ -1671,9 +1673,9 @@ static int binaryOperatorFromTagName( const QString &tagName )
|
||||
return BINARY_OPERATORS_TAG_NAMES_MAP.value( tagName, -1 );
|
||||
}
|
||||
|
||||
static QString binaryOperatorToTagName( QgsExpression::BinaryOperator op )
|
||||
static QString binaryOperatorToTagName( QgsExpressionNodeBinaryOperator::BinaryOperator op )
|
||||
{
|
||||
if ( op == QgsExpression::boILike )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boILike )
|
||||
{
|
||||
return QStringLiteral( "PropertyIsLike" );
|
||||
}
|
||||
@ -1700,7 +1702,7 @@ static bool isSpatialOperator( const QString &tagName )
|
||||
|
||||
|
||||
|
||||
QgsExpression::Node *QgsOgcUtils::nodeFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNode *QgsOgcUtils::nodeFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.isNull() )
|
||||
return nullptr;
|
||||
@ -1750,7 +1752,7 @@ QgsExpression::Node *QgsOgcUtils::nodeFromOgcFilter( QDomElement &element, QStri
|
||||
|
||||
|
||||
|
||||
QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.isNull() )
|
||||
return nullptr;
|
||||
@ -1763,13 +1765,13 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( op == QgsExpression::boLike && element.hasAttribute( QStringLiteral( "matchCase" ) ) && element.attribute( QStringLiteral( "matchCase" ) ) == QLatin1String( "false" ) )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boLike && element.hasAttribute( QStringLiteral( "matchCase" ) ) && element.attribute( QStringLiteral( "matchCase" ) ) == QLatin1String( "false" ) )
|
||||
{
|
||||
op = QgsExpression::boILike;
|
||||
op = QgsExpressionNodeBinaryOperator::boILike;
|
||||
}
|
||||
|
||||
QDomElement operandElem = element.firstChildElement();
|
||||
QgsExpression::Node *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
|
||||
QgsExpressionNode *expr = nodeFromOgcFilter( operandElem, errorMessage ), *leftOp = expr;
|
||||
if ( !expr )
|
||||
{
|
||||
if ( errorMessage.isEmpty() )
|
||||
@ -1779,7 +1781,7 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
|
||||
for ( operandElem = operandElem.nextSiblingElement(); !operandElem.isNull(); operandElem = operandElem.nextSiblingElement() )
|
||||
{
|
||||
QgsExpression::Node *opRight = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
QgsExpressionNode *opRight = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
if ( !opRight )
|
||||
{
|
||||
if ( errorMessage.isEmpty() )
|
||||
@ -1788,7 +1790,7 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( op == QgsExpression::boLike || op == QgsExpression::boILike )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boLike || op == QgsExpressionNodeBinaryOperator::boILike )
|
||||
{
|
||||
QString wildCard;
|
||||
if ( element.hasAttribute( QStringLiteral( "wildCard" ) ) )
|
||||
@ -1806,7 +1808,7 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
escape = element.attribute( QStringLiteral( "escape" ) );
|
||||
}
|
||||
// replace
|
||||
QString oprValue = static_cast<const QgsExpression::NodeLiteral *>( opRight )->value().toString();
|
||||
QString oprValue = static_cast<const QgsExpressionNodeLiteral *>( opRight )->value().toString();
|
||||
if ( !wildCard.isEmpty() && wildCard != QLatin1String( "%" ) )
|
||||
{
|
||||
oprValue.replace( '%', QLatin1String( "\\%" ) );
|
||||
@ -1843,10 +1845,10 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
{
|
||||
oprValue.replace( escape + escape, escape );
|
||||
}
|
||||
opRight = new QgsExpression::NodeLiteral( oprValue );
|
||||
opRight = new QgsExpressionNodeLiteral( oprValue );
|
||||
}
|
||||
|
||||
expr = new QgsExpression::NodeBinaryOperator( static_cast< QgsExpression::BinaryOperator >( op ), expr, opRight );
|
||||
expr = new QgsExpressionNodeBinaryOperator( static_cast< QgsExpressionNodeBinaryOperator::BinaryOperator >( op ), expr, opRight );
|
||||
}
|
||||
|
||||
if ( expr == leftOp )
|
||||
@ -1857,7 +1859,7 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpression::NodeBinaryOperator *ret = dynamic_cast< QgsExpression::NodeBinaryOperator * >( expr );
|
||||
QgsExpressionNodeBinaryOperator *ret = dynamic_cast< QgsExpressionNodeBinaryOperator * >( expr );
|
||||
if ( !ret )
|
||||
delete expr;
|
||||
|
||||
@ -1865,12 +1867,12 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::NodeFunction *QgsOgcUtils::nodeSpatialOperatorFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeFunction *QgsOgcUtils::nodeSpatialOperatorFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
// we are exploiting the fact that our function names are the same as the XML tag names
|
||||
int opIdx = QgsExpression::functionIndex( element.tagName().toLower() );
|
||||
|
||||
QgsExpression::NodeList *gml2Args = new QgsExpression::NodeList();
|
||||
QgsExpressionNode::NodeList *gml2Args = new QgsExpressionNode::NodeList();
|
||||
QDomElement childElem = element.firstChildElement();
|
||||
QString gml2Str;
|
||||
while ( !childElem.isNull() && gml2Str.isEmpty() )
|
||||
@ -1884,7 +1886,7 @@ QgsExpression::NodeFunction *QgsOgcUtils::nodeSpatialOperatorFromOgcFilter( QDom
|
||||
}
|
||||
if ( !gml2Str.isEmpty() )
|
||||
{
|
||||
gml2Args->append( new QgsExpression::NodeLiteral( QVariant( gml2Str.remove( '\n' ) ) ) );
|
||||
gml2Args->append( new QgsExpressionNodeLiteral( QVariant( gml2Str.remove( '\n' ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1893,21 +1895,21 @@ QgsExpression::NodeFunction *QgsOgcUtils::nodeSpatialOperatorFromOgcFilter( QDom
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpression::NodeList *opArgs = new QgsExpression::NodeList();
|
||||
opArgs->append( new QgsExpression::NodeFunction( QgsExpression::functionIndex( QStringLiteral( "$geometry" ) ), new QgsExpression::NodeList() ) );
|
||||
opArgs->append( new QgsExpression::NodeFunction( QgsExpression::functionIndex( QStringLiteral( "geomFromGML" ) ), gml2Args ) );
|
||||
QgsExpressionNode::NodeList *opArgs = new QgsExpressionNode::NodeList();
|
||||
opArgs->append( new QgsExpressionNodeFunction( QgsExpression::functionIndex( QStringLiteral( "$geometry" ) ), new QgsExpressionNode::NodeList() ) );
|
||||
opArgs->append( new QgsExpressionNodeFunction( QgsExpression::functionIndex( QStringLiteral( "geomFromGML" ) ), gml2Args ) );
|
||||
|
||||
return new QgsExpression::NodeFunction( opIdx, opArgs );
|
||||
return new QgsExpressionNodeFunction( opIdx, opArgs );
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::NodeUnaryOperator *QgsOgcUtils::nodeNotFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeUnaryOperator *QgsOgcUtils::nodeNotFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.tagName() != QLatin1String( "Not" ) )
|
||||
return nullptr;
|
||||
|
||||
QDomElement operandElem = element.firstChildElement();
|
||||
QgsExpression::Node *operand = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
QgsExpressionNode *operand = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
if ( !operand )
|
||||
{
|
||||
if ( errorMessage.isEmpty() )
|
||||
@ -1915,11 +1917,11 @@ QgsExpression::NodeUnaryOperator *QgsOgcUtils::nodeNotFromOgcFilter( QDomElement
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new QgsExpression::NodeUnaryOperator( QgsExpression::uoNot, operand );
|
||||
return new QgsExpressionNodeUnaryOperator( QgsExpressionNodeUnaryOperator::uoNot, operand );
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::NodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.isNull() || element.tagName() != QLatin1String( "Function" ) )
|
||||
{
|
||||
@ -1929,17 +1931,17 @@ QgsExpression::NodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement
|
||||
|
||||
for ( int i = 0; i < QgsExpression::Functions().size(); i++ )
|
||||
{
|
||||
QgsExpression::Function *funcDef = QgsExpression::Functions()[i];
|
||||
QgsExpressionFunction *funcDef = QgsExpression::Functions()[i];
|
||||
|
||||
if ( element.attribute( QStringLiteral( "name" ) ) != funcDef->name() )
|
||||
continue;
|
||||
|
||||
QgsExpression::NodeList *args = new QgsExpression::NodeList();
|
||||
QgsExpressionNode::NodeList *args = new QgsExpressionNode::NodeList();
|
||||
|
||||
QDomElement operandElem = element.firstChildElement();
|
||||
while ( !operandElem.isNull() )
|
||||
{
|
||||
QgsExpression::Node *op = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
QgsExpressionNode *op = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
if ( !op )
|
||||
{
|
||||
delete args;
|
||||
@ -1950,7 +1952,7 @@ QgsExpression::NodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement
|
||||
operandElem = operandElem.nextSiblingElement();
|
||||
}
|
||||
|
||||
return new QgsExpression::NodeFunction( i, args );
|
||||
return new QgsExpressionNodeFunction( i, args );
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -1958,7 +1960,7 @@ QgsExpression::NodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement
|
||||
|
||||
|
||||
|
||||
QgsExpression::Node *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNode *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.isNull() || element.tagName() != QLatin1String( "Literal" ) )
|
||||
{
|
||||
@ -1966,13 +1968,13 @@ QgsExpression::Node *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpression::Node *root = nullptr;
|
||||
QgsExpressionNode *root = nullptr;
|
||||
|
||||
// the literal content can have more children (e.g. CDATA section, text, ...)
|
||||
QDomNode childNode = element.firstChild();
|
||||
while ( !childNode.isNull() )
|
||||
{
|
||||
QgsExpression::Node *operand = nullptr;
|
||||
QgsExpressionNode *operand = nullptr;
|
||||
|
||||
if ( childNode.nodeType() == QDomNode::ElementNode )
|
||||
{
|
||||
@ -2000,7 +2002,7 @@ QgsExpression::Node *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element
|
||||
if ( ok )
|
||||
value = d;
|
||||
|
||||
operand = new QgsExpression::NodeLiteral( value );
|
||||
operand = new QgsExpressionNodeLiteral( value );
|
||||
if ( !operand )
|
||||
continue;
|
||||
}
|
||||
@ -2012,7 +2014,7 @@ QgsExpression::Node *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element
|
||||
}
|
||||
else
|
||||
{
|
||||
root = new QgsExpression::NodeBinaryOperator( QgsExpression::boConcat, root, operand );
|
||||
root = new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boConcat, root, operand );
|
||||
}
|
||||
|
||||
childNode = childNode.nextSibling();
|
||||
@ -2025,7 +2027,7 @@ QgsExpression::Node *QgsOgcUtils::nodeLiteralFromOgcFilter( QDomElement &element
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::NodeColumnRef *QgsOgcUtils::nodeColumnRefFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeColumnRef *QgsOgcUtils::nodeColumnRefFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
if ( element.isNull() || element.tagName() != QLatin1String( "PropertyName" ) )
|
||||
{
|
||||
@ -2033,15 +2035,15 @@ QgsExpression::NodeColumnRef *QgsOgcUtils::nodeColumnRefFromOgcFilter( QDomEleme
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new QgsExpression::NodeColumnRef( element.firstChild().nodeValue() );
|
||||
return new QgsExpressionNodeColumnRef( element.firstChild().nodeValue() );
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::Node *QgsOgcUtils::nodeIsBetweenFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNode *QgsOgcUtils::nodeIsBetweenFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
// <ogc:PropertyIsBetween> encode a Range check
|
||||
QgsExpression::Node *operand = nullptr, *lowerBound = nullptr;
|
||||
QgsExpression::Node *operand2 = nullptr, *upperBound = nullptr;
|
||||
QgsExpressionNode *operand = nullptr, *lowerBound = nullptr;
|
||||
QgsExpressionNode *operand2 = nullptr, *upperBound = nullptr;
|
||||
|
||||
QDomElement operandElem = element.firstChildElement();
|
||||
while ( !operandElem.isNull() )
|
||||
@ -2086,13 +2088,13 @@ QgsExpression::Node *QgsOgcUtils::nodeIsBetweenFromOgcFilter( QDomElement &eleme
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QgsExpression::Node *geOperator = new QgsExpression::NodeBinaryOperator( QgsExpression::boGE, operand, lowerBound );
|
||||
QgsExpression::Node *leOperator = new QgsExpression::NodeBinaryOperator( QgsExpression::boLE, operand2, upperBound );
|
||||
return new QgsExpression::NodeBinaryOperator( QgsExpression::boAnd, geOperator, leOperator );
|
||||
QgsExpressionNode *geOperator = new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boGE, operand, lowerBound );
|
||||
QgsExpressionNode *leOperator = new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boLE, operand2, upperBound );
|
||||
return new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boAnd, geOperator, leOperator );
|
||||
}
|
||||
|
||||
|
||||
QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodePropertyIsNullFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
QgsExpressionNodeBinaryOperator *QgsOgcUtils::nodePropertyIsNullFromOgcFilter( QDomElement &element, QString &errorMessage )
|
||||
{
|
||||
// convert ogc:PropertyIsNull to IS operator with NULL right operand
|
||||
if ( element.tagName() != QLatin1String( "PropertyIsNull" ) )
|
||||
@ -2101,12 +2103,12 @@ QgsExpression::NodeBinaryOperator *QgsOgcUtils::nodePropertyIsNullFromOgcFilter(
|
||||
}
|
||||
|
||||
QDomElement operandElem = element.firstChildElement();
|
||||
QgsExpression::Node *opLeft = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
QgsExpressionNode *opLeft = nodeFromOgcFilter( operandElem, errorMessage );
|
||||
if ( !opLeft )
|
||||
return nullptr;
|
||||
|
||||
QgsExpression::Node *opRight = new QgsExpression::NodeLiteral( QVariant() );
|
||||
return new QgsExpression::NodeBinaryOperator( QgsExpression::boIs, opLeft, opRight );
|
||||
QgsExpressionNode *opRight = new QgsExpressionNodeLiteral( QVariant() );
|
||||
return new QgsExpressionNodeBinaryOperator( QgsExpressionNodeBinaryOperator::boIs, opLeft, opRight );
|
||||
}
|
||||
|
||||
|
||||
@ -2172,15 +2174,15 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
|
||||
bool invertAxisOrientation,
|
||||
QString *errorMessage )
|
||||
{
|
||||
const QgsExpression::Node *node = exp.rootNode();
|
||||
const QgsExpressionNode *node = exp.rootNode();
|
||||
if ( !node )
|
||||
return QDomElement();
|
||||
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntFunction:
|
||||
case QgsExpression::ntLiteral:
|
||||
case QgsExpression::ntColumnRef:
|
||||
case QgsExpressionNode::ntFunction:
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
{
|
||||
QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
|
||||
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( node );
|
||||
@ -2243,22 +2245,22 @@ QDomElement QgsOgcUtils::SQLStatementToOgcFilter( const QgsSQLStatement &stateme
|
||||
//
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpression::Node *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpressionNode *node )
|
||||
{
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntUnaryOperator:
|
||||
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeUnaryOperator *>( node ) );
|
||||
case QgsExpression::ntBinaryOperator:
|
||||
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpression::NodeBinaryOperator *>( node ) );
|
||||
case QgsExpression::ntInOperator:
|
||||
return expressionInOperatorToOgcFilter( static_cast<const QgsExpression::NodeInOperator *>( node ) );
|
||||
case QgsExpression::ntFunction:
|
||||
return expressionFunctionToOgcFilter( static_cast<const QgsExpression::NodeFunction *>( node ) );
|
||||
case QgsExpression::ntLiteral:
|
||||
return expressionLiteralToOgcFilter( static_cast<const QgsExpression::NodeLiteral *>( node ) );
|
||||
case QgsExpression::ntColumnRef:
|
||||
return expressionColumnRefToOgcFilter( static_cast<const QgsExpression::NodeColumnRef *>( node ) );
|
||||
case QgsExpressionNode::ntUnaryOperator:
|
||||
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ) );
|
||||
case QgsExpressionNode::ntBinaryOperator:
|
||||
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
|
||||
case QgsExpressionNode::ntInOperator:
|
||||
return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ) );
|
||||
case QgsExpressionNode::ntFunction:
|
||||
return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ) );
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ) );
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ) );
|
||||
|
||||
default:
|
||||
mErrorMessage = QObject::tr( "Node type not supported: %1" ).arg( node->nodeType() );
|
||||
@ -2267,7 +2269,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpress
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpression::NodeUnaryOperator *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node )
|
||||
{
|
||||
|
||||
QDomElement operandElem = expressionNodeToOgcFilter( node->operand() );
|
||||
@ -2277,9 +2279,9 @@ QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const Q
|
||||
QDomElement uoElem;
|
||||
switch ( node->op() )
|
||||
{
|
||||
case QgsExpression::uoMinus:
|
||||
case QgsExpressionNodeUnaryOperator::uoMinus:
|
||||
uoElem = mDoc.createElement( mFilterPrefix + ":Literal" );
|
||||
if ( node->operand()->nodeType() == QgsExpression::ntLiteral )
|
||||
if ( node->operand()->nodeType() == QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
// operand expression already created a Literal node:
|
||||
// take the literal value, prepend - and remove old literal node
|
||||
@ -2292,13 +2294,13 @@ QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const Q
|
||||
return QDomElement();
|
||||
}
|
||||
break;
|
||||
case QgsExpression::uoNot:
|
||||
case QgsExpressionNodeUnaryOperator::uoNot:
|
||||
uoElem = mDoc.createElement( mFilterPrefix + ":Not" );
|
||||
uoElem.appendChild( operandElem );
|
||||
break;
|
||||
|
||||
default:
|
||||
mErrorMessage = QObject::tr( "Unary operator %1 not implemented yet" ).arg( QgsExpression::UNARY_OPERATOR_TEXT[node->op()] );
|
||||
mErrorMessage = QObject::tr( "Unary operator '%1' not implemented yet" ).arg( node->text() );
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
@ -2306,27 +2308,27 @@ QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const Q
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpression::NodeBinaryOperator *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node )
|
||||
{
|
||||
QDomElement leftElem = expressionNodeToOgcFilter( node->opLeft() );
|
||||
if ( !mErrorMessage.isEmpty() )
|
||||
return QDomElement();
|
||||
|
||||
QgsExpression::BinaryOperator op = node->op();
|
||||
QgsExpressionNodeBinaryOperator::BinaryOperator op = node->op();
|
||||
|
||||
// before right operator is parsed: to allow NULL handling
|
||||
if ( op == QgsExpression::boIs || op == QgsExpression::boIsNot )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boIs || op == QgsExpressionNodeBinaryOperator::boIsNot )
|
||||
{
|
||||
if ( node->opRight()->nodeType() == QgsExpression::ntLiteral )
|
||||
if ( node->opRight()->nodeType() == QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
const QgsExpression::NodeLiteral *rightLit = static_cast<const QgsExpression::NodeLiteral *>( node->opRight() );
|
||||
const QgsExpressionNodeLiteral *rightLit = static_cast<const QgsExpressionNodeLiteral *>( node->opRight() );
|
||||
if ( rightLit->value().isNull() )
|
||||
{
|
||||
|
||||
QDomElement elem = mDoc.createElement( mFilterPrefix + ":PropertyIsNull" );
|
||||
elem.appendChild( leftElem );
|
||||
|
||||
if ( op == QgsExpression::boIsNot )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boIsNot )
|
||||
{
|
||||
QDomElement notElem = mDoc.createElement( mFilterPrefix + ":Not" );
|
||||
notElem.appendChild( elem );
|
||||
@ -2337,7 +2339,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
|
||||
}
|
||||
|
||||
// continue with equal / not equal operator once the null case is handled
|
||||
op = ( op == QgsExpression::boIs ? QgsExpression::boEQ : QgsExpression::boNE );
|
||||
op = ( op == QgsExpressionNodeBinaryOperator::boIs ? QgsExpressionNodeBinaryOperator::boEQ : QgsExpressionNodeBinaryOperator::boNE );
|
||||
}
|
||||
|
||||
}
|
||||
@ -2352,15 +2354,15 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
|
||||
{
|
||||
// not implemented binary operators
|
||||
// TODO: regex, % (mod), ^ (pow) are not supported yet
|
||||
mErrorMessage = QObject::tr( "Binary operator %1 not implemented yet" ).arg( QgsExpression::BINARY_OPERATOR_TEXT[op] );
|
||||
mErrorMessage = QObject::tr( "Binary operator %1 not implemented yet" ).arg( node->text() );
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
QDomElement boElem = mDoc.createElement( mFilterPrefix + ":" + opText );
|
||||
|
||||
if ( op == QgsExpression::boLike || op == QgsExpression::boILike )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boLike || op == QgsExpressionNodeBinaryOperator::boILike )
|
||||
{
|
||||
if ( op == QgsExpression::boILike )
|
||||
if ( op == QgsExpressionNodeBinaryOperator::boILike )
|
||||
boElem.setAttribute( QStringLiteral( "matchCase" ), QStringLiteral( "false" ) );
|
||||
|
||||
// setup wildCards to <ogc:PropertyIsLike>
|
||||
@ -2378,7 +2380,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpression::NodeLiteral *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node )
|
||||
{
|
||||
QString value;
|
||||
switch ( node->value().type() )
|
||||
@ -2404,7 +2406,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpr
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpression::NodeColumnRef *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node )
|
||||
{
|
||||
QDomElement propElem = mDoc.createElement( mFilterPrefix + ":" + mPropertyName );
|
||||
propElem.appendChild( mDoc.createTextNode( node->name() ) );
|
||||
@ -2413,7 +2415,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsEx
|
||||
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpression::NodeInOperator *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node )
|
||||
{
|
||||
if ( node->list()->list().size() == 1 )
|
||||
return expressionNodeToOgcFilter( node->list()->list()[0] );
|
||||
@ -2421,7 +2423,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsE
|
||||
QDomElement orElem = mDoc.createElement( mFilterPrefix + ":Or" );
|
||||
QDomElement leftNode = expressionNodeToOgcFilter( node->node() );
|
||||
|
||||
Q_FOREACH ( QgsExpression::Node *n, node->list()->list() )
|
||||
Q_FOREACH ( QgsExpressionNode *n, node->list()->list() )
|
||||
{
|
||||
QDomElement listNode = expressionNodeToOgcFilter( n );
|
||||
if ( !mErrorMessage.isEmpty() )
|
||||
@ -2465,31 +2467,31 @@ static QString tagNameForSpatialOperator( const QString &fnName )
|
||||
return BINARY_SPATIAL_OPS_MAP.value( fnName );
|
||||
}
|
||||
|
||||
static bool isGeometryColumn( const QgsExpression::Node *node )
|
||||
static bool isGeometryColumn( const QgsExpressionNode *node )
|
||||
{
|
||||
if ( node->nodeType() != QgsExpression::ntFunction )
|
||||
if ( node->nodeType() != QgsExpressionNode::ntFunction )
|
||||
return false;
|
||||
|
||||
const QgsExpression::NodeFunction *fn = static_cast<const QgsExpression::NodeFunction *>( node );
|
||||
QgsExpression::Function *fd = QgsExpression::Functions()[fn->fnIndex()];
|
||||
const QgsExpressionNodeFunction *fn = static_cast<const QgsExpressionNodeFunction *>( node );
|
||||
QgsExpressionFunction *fd = QgsExpression::Functions()[fn->fnIndex()];
|
||||
return fd->name() == QLatin1String( "$geometry" );
|
||||
}
|
||||
|
||||
static QgsGeometry geometryFromConstExpr( const QgsExpression::Node *node )
|
||||
static QgsGeometry geometryFromConstExpr( const QgsExpressionNode *node )
|
||||
{
|
||||
// Right now we support only geomFromWKT(' ..... ')
|
||||
// Ideally we should support any constant sub-expression (not dependent on feature's geometry or attributes)
|
||||
|
||||
if ( node->nodeType() == QgsExpression::ntFunction )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntFunction )
|
||||
{
|
||||
const QgsExpression::NodeFunction *fnNode = static_cast<const QgsExpression::NodeFunction *>( node );
|
||||
QgsExpression::Function *fnDef = QgsExpression::Functions()[fnNode->fnIndex()];
|
||||
const QgsExpressionNodeFunction *fnNode = static_cast<const QgsExpressionNodeFunction *>( node );
|
||||
QgsExpressionFunction *fnDef = QgsExpression::Functions()[fnNode->fnIndex()];
|
||||
if ( fnDef->name() == QLatin1String( "geom_from_wkt" ) )
|
||||
{
|
||||
const QList<QgsExpression::Node *> &args = fnNode->args()->list();
|
||||
if ( args[0]->nodeType() == QgsExpression::ntLiteral )
|
||||
const QList<QgsExpressionNode *> &args = fnNode->args()->list();
|
||||
if ( args[0]->nodeType() == QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
QString wkt = static_cast<const QgsExpression::NodeLiteral *>( args[0] )->value().toString();
|
||||
QString wkt = static_cast<const QgsExpressionNodeLiteral *>( args[0] )->value().toString();
|
||||
return QgsGeometry::fromWkt( wkt );
|
||||
}
|
||||
}
|
||||
@ -2498,13 +2500,13 @@ static QgsGeometry geometryFromConstExpr( const QgsExpression::Node *node )
|
||||
}
|
||||
|
||||
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpression::NodeFunction *node )
|
||||
QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node )
|
||||
{
|
||||
QgsExpression::Function *fd = QgsExpression::Functions()[node->fnIndex()];
|
||||
QgsExpressionFunction *fd = QgsExpression::Functions()[node->fnIndex()];
|
||||
|
||||
if ( fd->name() == QLatin1String( "intersects_bbox" ) )
|
||||
{
|
||||
QList<QgsExpression::Node *> argNodes = node->args()->list();
|
||||
QList<QgsExpressionNode *> argNodes = node->args()->list();
|
||||
Q_ASSERT( argNodes.count() == 2 ); // binary spatial ops must have two args
|
||||
|
||||
QgsGeometry geom = geometryFromConstExpr( argNodes[1] );
|
||||
@ -2535,10 +2537,10 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
|
||||
|
||||
if ( isBinarySpatialOperator( fd->name() ) )
|
||||
{
|
||||
QList<QgsExpression::Node *> argNodes = node->args()->list();
|
||||
QList<QgsExpressionNode *> argNodes = node->args()->list();
|
||||
Q_ASSERT( argNodes.count() == 2 ); // binary spatial ops must have two args
|
||||
|
||||
QgsExpression::Node *otherNode = nullptr;
|
||||
QgsExpressionNode *otherNode = nullptr;
|
||||
if ( isGeometryColumn( argNodes[0] ) )
|
||||
otherNode = argNodes[1];
|
||||
else if ( isGeometryColumn( argNodes[1] ) )
|
||||
@ -2552,23 +2554,23 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
|
||||
QDomElement otherGeomElem;
|
||||
|
||||
// the other node must be a geometry constructor
|
||||
if ( otherNode->nodeType() != QgsExpression::ntFunction )
|
||||
if ( otherNode->nodeType() != QgsExpressionNode::ntFunction )
|
||||
{
|
||||
mErrorMessage = QObject::tr( "spatial operator: the other operator must be a geometry constructor function" );
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
const QgsExpression::NodeFunction *otherFn = static_cast<const QgsExpression::NodeFunction *>( otherNode );
|
||||
QgsExpression::Function *otherFnDef = QgsExpression::Functions()[otherFn->fnIndex()];
|
||||
const QgsExpressionNodeFunction *otherFn = static_cast<const QgsExpressionNodeFunction *>( otherNode );
|
||||
QgsExpressionFunction *otherFnDef = QgsExpression::Functions()[otherFn->fnIndex()];
|
||||
if ( otherFnDef->name() == QLatin1String( "geom_from_wkt" ) )
|
||||
{
|
||||
QgsExpression::Node *firstFnArg = otherFn->args()->list()[0];
|
||||
if ( firstFnArg->nodeType() != QgsExpression::ntLiteral )
|
||||
QgsExpressionNode *firstFnArg = otherFn->args()->list()[0];
|
||||
if ( firstFnArg->nodeType() != QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
mErrorMessage = QObject::tr( "geom_from_wkt: argument must be string literal" );
|
||||
return QDomElement();
|
||||
}
|
||||
QString wkt = static_cast<const QgsExpression::NodeLiteral *>( firstFnArg )->value().toString();
|
||||
QString wkt = static_cast<const QgsExpressionNodeLiteral *>( firstFnArg )->value().toString();
|
||||
QgsGeometry geom = QgsGeometry::fromWkt( wkt );
|
||||
otherGeomElem = QgsOgcUtils::geometryToGML( &geom, mDoc, mGMLVersion, mSrsName, mInvertAxisOrientation,
|
||||
QStringLiteral( "qgis_id_geom_%1" ).arg( mGeomId ) );
|
||||
@ -2576,15 +2578,15 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
|
||||
}
|
||||
else if ( otherFnDef->name() == QLatin1String( "geom_from_gml" ) )
|
||||
{
|
||||
QgsExpression::Node *firstFnArg = otherFn->args()->list()[0];
|
||||
if ( firstFnArg->nodeType() != QgsExpression::ntLiteral )
|
||||
QgsExpressionNode *firstFnArg = otherFn->args()->list()[0];
|
||||
if ( firstFnArg->nodeType() != QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
mErrorMessage = QObject::tr( "geom_from_gml: argument must be string literal" );
|
||||
return QDomElement();
|
||||
}
|
||||
|
||||
QDomDocument geomDoc;
|
||||
QString gml = static_cast<const QgsExpression::NodeLiteral *>( firstFnArg )->value().toString();
|
||||
QString gml = static_cast<const QgsExpressionNodeLiteral *>( firstFnArg )->value().toString();
|
||||
if ( !geomDoc.setContent( gml, true ) )
|
||||
{
|
||||
mErrorMessage = QObject::tr( "geom_from_gml: unable to parse XML" );
|
||||
@ -2619,7 +2621,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
|
||||
// this is somehow wrong - we are just hoping that the other side supports the same functions as we do...
|
||||
QDomElement funcElem = mDoc.createElement( mFilterPrefix + ":Function" );
|
||||
funcElem.setAttribute( QStringLiteral( "name" ), fd->name() );
|
||||
Q_FOREACH ( QgsExpression::Node *n, node->args()->list() )
|
||||
Q_FOREACH ( QgsExpressionNode *n, node->args()->list() )
|
||||
{
|
||||
QDomElement childElem = expressionNodeToOgcFilter( n );
|
||||
if ( !mErrorMessage.isEmpty() )
|
||||
|
@ -34,6 +34,8 @@ class QgsRectangle;
|
||||
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionnode.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgssqlstatement.h"
|
||||
|
||||
/** \ingroup core
|
||||
@ -275,23 +277,23 @@ class CORE_EXPORT QgsOgcUtils
|
||||
static QDomElement createGMLPositions( const QgsPolyline &points, QDomDocument &doc );
|
||||
|
||||
//! handle a generic sub-expression
|
||||
static QgsExpression::Node *nodeFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNode *nodeFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handle a generic binary operator
|
||||
static QgsExpression::NodeBinaryOperator *nodeBinaryOperatorFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeBinaryOperator *nodeBinaryOperatorFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles various spatial operation tags (\verbatim <Intersects> \endverbatim, \verbatim <Touches> \endverbatim etc.)
|
||||
static QgsExpression::NodeFunction *nodeSpatialOperatorFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeFunction *nodeSpatialOperatorFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handle \verbatim <Not> \endverbatim tag
|
||||
static QgsExpression::NodeUnaryOperator *nodeNotFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeUnaryOperator *nodeNotFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles \verbatim <Function> \endverbatim tag
|
||||
static QgsExpression::NodeFunction *nodeFunctionFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeFunction *nodeFunctionFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles \verbatim <Literal> \endverbatim tag
|
||||
static QgsExpression::Node *nodeLiteralFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNode *nodeLiteralFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles \verbatim <PropertyName> \endverbatim tag
|
||||
static QgsExpression::NodeColumnRef *nodeColumnRefFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeColumnRef *nodeColumnRefFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles \verbatim <PropertyIsBetween> \endverbatim tag
|
||||
static QgsExpression::Node *nodeIsBetweenFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNode *nodeIsBetweenFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
//! handles \verbatim <PropertyIsNull> \endverbatim tag
|
||||
static QgsExpression::NodeBinaryOperator *nodePropertyIsNullFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
static QgsExpressionNodeBinaryOperator *nodePropertyIsNullFromOgcFilter( QDomElement &element, QString &errorMessage );
|
||||
};
|
||||
|
||||
#ifndef SIP_RUN
|
||||
@ -313,7 +315,7 @@ class QgsOgcUtilsExprToFilter
|
||||
bool invertAxisOrientation );
|
||||
|
||||
//! Convert an expression to a OGC filter
|
||||
QDomElement expressionNodeToOgcFilter( const QgsExpression::Node *node );
|
||||
QDomElement expressionNodeToOgcFilter( const QgsExpressionNode *node );
|
||||
|
||||
//! Return whether the gml: namespace is used
|
||||
bool GMLNamespaceUsed() const { return mGMLUsed; }
|
||||
@ -334,12 +336,12 @@ class QgsOgcUtilsExprToFilter
|
||||
QString mPropertyName;
|
||||
int mGeomId;
|
||||
|
||||
QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpression::NodeUnaryOperator *node );
|
||||
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpression::NodeBinaryOperator *node );
|
||||
QDomElement expressionLiteralToOgcFilter( const QgsExpression::NodeLiteral *node );
|
||||
QDomElement expressionColumnRefToOgcFilter( const QgsExpression::NodeColumnRef *node );
|
||||
QDomElement expressionInOperatorToOgcFilter( const QgsExpression::NodeInOperator *node );
|
||||
QDomElement expressionFunctionToOgcFilter( const QgsExpression::NodeFunction *node );
|
||||
QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node );
|
||||
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node );
|
||||
QDomElement expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node );
|
||||
QDomElement expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node );
|
||||
QDomElement expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node );
|
||||
QDomElement expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node );
|
||||
};
|
||||
|
||||
/** \ingroup core
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "qgslogger.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgscolorramp.h"
|
||||
@ -251,17 +252,17 @@ QgsGenericNumericTransformer *QgsGenericNumericTransformer::fromExpression( cons
|
||||
if ( !e.rootNode() )
|
||||
return nullptr;
|
||||
|
||||
const QgsExpression::NodeFunction *f = dynamic_cast<const QgsExpression::NodeFunction *>( e.rootNode() );
|
||||
const QgsExpressionNodeFunction *f = dynamic_cast<const QgsExpressionNodeFunction *>( e.rootNode() );
|
||||
if ( !f )
|
||||
return nullptr;
|
||||
|
||||
QList<QgsExpression::Node *> args = f->args()->list();
|
||||
QList<QgsExpressionNode *> args = f->args()->list();
|
||||
|
||||
// the scale function may be enclosed in a coalesce(expr, 0) to avoid NULL value
|
||||
// to be drawn with the default size
|
||||
if ( "coalesce" == QgsExpression::Functions()[f->fnIndex()]->name() )
|
||||
{
|
||||
f = dynamic_cast<const QgsExpression::NodeFunction *>( args[0] );
|
||||
f = dynamic_cast<const QgsExpressionNodeFunction *>( args[0] );
|
||||
if ( !f )
|
||||
return nullptr;
|
||||
nullValue = QgsExpression( args[1]->dump() ).evaluate().toDouble( &ok );
|
||||
@ -298,9 +299,9 @@ QgsGenericNumericTransformer *QgsGenericNumericTransformer::fromExpression( cons
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( args[0]->nodeType() == QgsExpression::ntColumnRef )
|
||||
if ( args[0]->nodeType() == QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
fieldName = static_cast< QgsExpression::NodeColumnRef * >( args[0] )->name();
|
||||
fieldName = static_cast< QgsExpressionNodeColumnRef * >( args[0] )->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -485,17 +486,17 @@ QgsSizeScaleTransformer *QgsSizeScaleTransformer::fromExpression( const QString
|
||||
if ( !e.rootNode() )
|
||||
return nullptr;
|
||||
|
||||
const QgsExpression::NodeFunction *f = dynamic_cast<const QgsExpression::NodeFunction *>( e.rootNode() );
|
||||
const QgsExpressionNodeFunction *f = dynamic_cast<const QgsExpressionNodeFunction *>( e.rootNode() );
|
||||
if ( !f )
|
||||
return nullptr;
|
||||
|
||||
QList<QgsExpression::Node *> args = f->args()->list();
|
||||
QList<QgsExpressionNode *> args = f->args()->list();
|
||||
|
||||
// the scale function may be enclosed in a coalesce(expr, 0) to avoid NULL value
|
||||
// to be drawn with the default size
|
||||
if ( "coalesce" == QgsExpression::Functions()[f->fnIndex()]->name() )
|
||||
{
|
||||
f = dynamic_cast<const QgsExpression::NodeFunction *>( args[0] );
|
||||
f = dynamic_cast<const QgsExpressionNodeFunction *>( args[0] );
|
||||
if ( !f )
|
||||
return nullptr;
|
||||
nullSize = QgsExpression( args[1]->dump() ).evaluate().toDouble( &ok );
|
||||
@ -540,9 +541,9 @@ QgsSizeScaleTransformer *QgsSizeScaleTransformer::fromExpression( const QString
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( args[0]->nodeType() == QgsExpression::ntColumnRef )
|
||||
if ( args[0]->nodeType() == QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
fieldName = static_cast< QgsExpression::NodeColumnRef * >( args[0] )->name();
|
||||
fieldName = static_cast< QgsExpressionNodeColumnRef * >( args[0] )->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -14,6 +14,8 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgssqlexpressioncompiler.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
|
||||
QgsSqlExpressionCompiler::QgsSqlExpressionCompiler( const QgsFields &fields, Flags flags )
|
||||
: mResult( None )
|
||||
@ -71,16 +73,16 @@ QString QgsSqlExpressionCompiler::quotedValue( const QVariant &value, bool &ok )
|
||||
}
|
||||
}
|
||||
|
||||
QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const QgsExpression::Node *node, QString &result )
|
||||
QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
|
||||
{
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntUnaryOperator:
|
||||
case QgsExpressionNode::ntUnaryOperator:
|
||||
{
|
||||
const QgsExpression::NodeUnaryOperator *n = static_cast<const QgsExpression::NodeUnaryOperator *>( node );
|
||||
const QgsExpressionNodeUnaryOperator *n = static_cast<const QgsExpressionNodeUnaryOperator *>( node );
|
||||
switch ( n->op() )
|
||||
{
|
||||
case QgsExpression::uoNot:
|
||||
case QgsExpressionNodeUnaryOperator::uoNot:
|
||||
{
|
||||
QString right;
|
||||
if ( compileNode( n->operand(), right ) == Complete )
|
||||
@ -92,7 +94,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return Fail;
|
||||
}
|
||||
|
||||
case QgsExpression::uoMinus:
|
||||
case QgsExpressionNodeUnaryOperator::uoMinus:
|
||||
{
|
||||
if ( mFlags.testFlag( NoUnaryMinus ) )
|
||||
return Fail;
|
||||
@ -111,17 +113,17 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
break;
|
||||
}
|
||||
|
||||
case QgsExpression::ntBinaryOperator:
|
||||
case QgsExpressionNodeBinaryOperator::ntBinaryOperator:
|
||||
{
|
||||
const QgsExpression::NodeBinaryOperator *n = static_cast<const QgsExpression::NodeBinaryOperator *>( node );
|
||||
const QgsExpressionNodeBinaryOperator *n = static_cast<const QgsExpressionNodeBinaryOperator *>( node );
|
||||
|
||||
QString op;
|
||||
bool partialCompilation = false;
|
||||
bool failOnPartialNode = false;
|
||||
switch ( n->op() )
|
||||
{
|
||||
case QgsExpression::boEQ:
|
||||
if ( mFlags.testFlag( CaseInsensitiveStringMatch ) && n->opLeft()->nodeType() == QgsExpression::ntColumnRef && n->opRight()->nodeType() == QgsExpression::ntColumnRef )
|
||||
case QgsExpressionNodeBinaryOperator::boEQ:
|
||||
if ( mFlags.testFlag( CaseInsensitiveStringMatch ) && n->opLeft()->nodeType() == QgsExpressionNode::ntColumnRef && n->opRight()->nodeType() == QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
// equality between column refs results in a partial compilation, since provider is performing
|
||||
// case-insensitive matches between strings
|
||||
@ -131,50 +133,50 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
op = QStringLiteral( "=" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boGE:
|
||||
case QgsExpressionNodeBinaryOperator::boGE:
|
||||
op = QStringLiteral( ">=" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boGT:
|
||||
case QgsExpressionNodeBinaryOperator::boGT:
|
||||
op = QStringLiteral( ">" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boLE:
|
||||
case QgsExpressionNodeBinaryOperator::boLE:
|
||||
op = QStringLiteral( "<=" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boLT:
|
||||
case QgsExpressionNodeBinaryOperator::boLT:
|
||||
op = QStringLiteral( "<" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boIs:
|
||||
case QgsExpressionNodeBinaryOperator::boIs:
|
||||
op = QStringLiteral( "IS" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boIsNot:
|
||||
case QgsExpressionNodeBinaryOperator::boIsNot:
|
||||
op = QStringLiteral( "IS NOT" );
|
||||
failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
|
||||
break;
|
||||
|
||||
case QgsExpression::boLike:
|
||||
case QgsExpressionNodeBinaryOperator::boLike:
|
||||
op = QStringLiteral( "LIKE" );
|
||||
partialCompilation = mFlags.testFlag( LikeIsCaseInsensitive );
|
||||
break;
|
||||
|
||||
case QgsExpression::boILike:
|
||||
case QgsExpressionNodeBinaryOperator::boILike:
|
||||
if ( mFlags.testFlag( LikeIsCaseInsensitive ) )
|
||||
op = QStringLiteral( "LIKE" );
|
||||
else
|
||||
op = QStringLiteral( "ILIKE" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boNotLike:
|
||||
case QgsExpressionNodeBinaryOperator::boNotLike:
|
||||
op = QStringLiteral( "NOT LIKE" );
|
||||
partialCompilation = mFlags.testFlag( LikeIsCaseInsensitive );
|
||||
failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
|
||||
break;
|
||||
|
||||
case QgsExpression::boNotILike:
|
||||
case QgsExpressionNodeBinaryOperator::boNotILike:
|
||||
failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
|
||||
if ( mFlags.testFlag( LikeIsCaseInsensitive ) )
|
||||
op = QStringLiteral( "NOT LIKE" );
|
||||
@ -182,7 +184,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
op = QStringLiteral( "NOT ILIKE" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boOr:
|
||||
case QgsExpressionNodeBinaryOperator::boOr:
|
||||
if ( mFlags.testFlag( NoNullInBooleanLogic ) )
|
||||
{
|
||||
if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
|
||||
@ -192,7 +194,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
op = QStringLiteral( "OR" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boAnd:
|
||||
case QgsExpressionNodeBinaryOperator::boAnd:
|
||||
if ( mFlags.testFlag( NoNullInBooleanLogic ) )
|
||||
{
|
||||
if ( nodeIsNullLiteral( n->opLeft() ) || nodeIsNullLiteral( n->opRight() ) )
|
||||
@ -202,44 +204,44 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
op = QStringLiteral( "AND" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boNE:
|
||||
case QgsExpressionNodeBinaryOperator::boNE:
|
||||
failOnPartialNode = mFlags.testFlag( CaseInsensitiveStringMatch );
|
||||
op = QStringLiteral( "<>" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boMul:
|
||||
case QgsExpressionNodeBinaryOperator::boMul:
|
||||
op = QStringLiteral( "*" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boPlus:
|
||||
case QgsExpressionNodeBinaryOperator::boPlus:
|
||||
op = QStringLiteral( "+" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boMinus:
|
||||
case QgsExpressionNodeBinaryOperator::boMinus:
|
||||
op = QStringLiteral( "-" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boDiv:
|
||||
case QgsExpressionNodeBinaryOperator::boDiv:
|
||||
op = QStringLiteral( "/" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boMod:
|
||||
case QgsExpressionNodeBinaryOperator::boMod:
|
||||
op = QStringLiteral( "%" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boConcat:
|
||||
case QgsExpressionNodeBinaryOperator::boConcat:
|
||||
op = QStringLiteral( "||" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boIntDiv:
|
||||
case QgsExpressionNodeBinaryOperator::boIntDiv:
|
||||
op = QStringLiteral( "/" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boPow:
|
||||
case QgsExpressionNodeBinaryOperator::boPow:
|
||||
op = QStringLiteral( "^" );
|
||||
break;
|
||||
|
||||
case QgsExpression::boRegexp:
|
||||
case QgsExpressionNodeBinaryOperator::boRegexp:
|
||||
op = QStringLiteral( "~" );
|
||||
break;
|
||||
}
|
||||
@ -256,7 +258,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
if ( failOnPartialNode && ( lr == Partial || rr == Partial ) )
|
||||
return Fail;
|
||||
|
||||
if ( n->op() == QgsExpression::boDiv && mFlags.testFlag( IntegerDivisionResultsInInteger ) )
|
||||
if ( n->op() == QgsExpressionNodeBinaryOperator::boDiv && mFlags.testFlag( IntegerDivisionResultsInInteger ) )
|
||||
{
|
||||
right = castToReal( right );
|
||||
if ( right.isEmpty() )
|
||||
@ -267,7 +269,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
}
|
||||
|
||||
result = '(' + left + ' ' + op + ' ' + right + ')';
|
||||
if ( n->op() == QgsExpression::boIntDiv )
|
||||
if ( n->op() == QgsExpressionNodeBinaryOperator::boIntDiv )
|
||||
{
|
||||
result = castToInt( result );
|
||||
if ( result.isEmpty() )
|
||||
@ -285,9 +287,9 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return Fail;
|
||||
}
|
||||
|
||||
case QgsExpression::ntLiteral:
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
{
|
||||
const QgsExpression::NodeLiteral *n = static_cast<const QgsExpression::NodeLiteral *>( node );
|
||||
const QgsExpressionNodeLiteral *n = static_cast<const QgsExpressionNodeLiteral *>( node );
|
||||
bool ok = false;
|
||||
if ( mFlags.testFlag( CaseInsensitiveStringMatch ) && n->value().type() == QVariant::String )
|
||||
{
|
||||
@ -303,9 +305,9 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
}
|
||||
}
|
||||
|
||||
case QgsExpression::ntColumnRef:
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
{
|
||||
const QgsExpression::NodeColumnRef *n = static_cast<const QgsExpression::NodeColumnRef *>( node );
|
||||
const QgsExpressionNodeColumnRef *n = static_cast<const QgsExpressionNodeColumnRef *>( node );
|
||||
|
||||
if ( mFields.indexFromName( n->name() ) == -1 )
|
||||
// Not a provider field
|
||||
@ -316,13 +318,13 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return Complete;
|
||||
}
|
||||
|
||||
case QgsExpression::ntInOperator:
|
||||
case QgsExpressionNode::ntInOperator:
|
||||
{
|
||||
const QgsExpression::NodeInOperator *n = static_cast<const QgsExpression::NodeInOperator *>( node );
|
||||
const QgsExpressionNodeInOperator *n = static_cast<const QgsExpressionNodeInOperator *>( node );
|
||||
QStringList list;
|
||||
|
||||
Result inResult = Complete;
|
||||
Q_FOREACH ( const QgsExpression::Node *ln, n->list()->list() )
|
||||
Q_FOREACH ( const QgsExpressionNode *ln, n->list()->list() )
|
||||
{
|
||||
QString s;
|
||||
Result r = compileNode( ln, s );
|
||||
@ -345,10 +347,10 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return ( inResult == Partial || rn == Partial ) ? Partial : Complete;
|
||||
}
|
||||
|
||||
case QgsExpression::ntFunction:
|
||||
case QgsExpressionNode::ntFunction:
|
||||
{
|
||||
const QgsExpression::NodeFunction *n = static_cast<const QgsExpression::NodeFunction *>( node );
|
||||
QgsExpression::Function *fd = QgsExpression::Functions()[n->fnIndex()];
|
||||
const QgsExpressionNodeFunction *n = static_cast<const QgsExpressionNodeFunction *>( node );
|
||||
QgsExpressionFunction *fd = QgsExpression::Functions()[n->fnIndex()];
|
||||
|
||||
// get sql function to compile node expression
|
||||
QString nd = sqlFunctionFromFunctionName( fd->name() );
|
||||
@ -359,7 +361,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
// compile arguments
|
||||
QStringList args;
|
||||
Result inResult = Complete;
|
||||
Q_FOREACH ( const QgsExpression::Node *ln, n->args()->list() )
|
||||
Q_FOREACH ( const QgsExpressionNode *ln, n->args()->list() )
|
||||
{
|
||||
QString s;
|
||||
Result r = compileNode( ln, s );
|
||||
@ -381,7 +383,7 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return inResult == Partial ? Partial : Complete;
|
||||
}
|
||||
|
||||
case QgsExpression::ntCondition:
|
||||
case QgsExpressionNode::ntCondition:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -412,11 +414,11 @@ QString QgsSqlExpressionCompiler::castToInt( const QString &value ) const
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool QgsSqlExpressionCompiler::nodeIsNullLiteral( const QgsExpression::Node *node ) const
|
||||
bool QgsSqlExpressionCompiler::nodeIsNullLiteral( const QgsExpressionNode *node ) const
|
||||
{
|
||||
if ( node->nodeType() != QgsExpression::ntLiteral )
|
||||
if ( node->nodeType() != QgsExpressionNode::ntLiteral )
|
||||
return false;
|
||||
|
||||
const QgsExpression::NodeLiteral *nLit = static_cast<const QgsExpression::NodeLiteral *>( node );
|
||||
const QgsExpressionNodeLiteral *nLit = static_cast<const QgsExpressionNodeLiteral *>( node );
|
||||
return nLit->value().isNull();
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ class CORE_EXPORT QgsSqlExpressionCompiler
|
||||
* \param str string representing compiled node should be stored in this parameter
|
||||
* \returns result of node compilation
|
||||
*/
|
||||
virtual Result compileNode( const QgsExpression::Node *node, QString &str );
|
||||
virtual Result compileNode( const QgsExpressionNode *node, QString &str );
|
||||
|
||||
/** Return the SQL function for the expression function.
|
||||
* Derived classes should override this to help compile functions
|
||||
@ -132,7 +132,7 @@ class CORE_EXPORT QgsSqlExpressionCompiler
|
||||
|
||||
Flags mFlags;
|
||||
|
||||
bool nodeIsNullLiteral( const QgsExpression::Node *node ) const;
|
||||
bool nodeIsNullLiteral( const QgsExpressionNode *node ) const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -17,22 +17,23 @@
|
||||
|
||||
#include "qgssqliteexpressioncompiler.h"
|
||||
#include "qgssqlexpressioncompiler.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
QgsSQLiteExpressionCompiler::QgsSQLiteExpressionCompiler( const QgsFields &fields )
|
||||
: QgsSqlExpressionCompiler( fields, QgsSqlExpressionCompiler::LikeIsCaseInsensitive | QgsSqlExpressionCompiler::IntegerDivisionResultsInInteger )
|
||||
{
|
||||
}
|
||||
|
||||
QgsSqlExpressionCompiler::Result QgsSQLiteExpressionCompiler::compileNode( const QgsExpression::Node *node, QString &result )
|
||||
QgsSqlExpressionCompiler::Result QgsSQLiteExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
|
||||
{
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntBinaryOperator:
|
||||
case QgsExpressionNode::ntBinaryOperator:
|
||||
{
|
||||
switch ( static_cast<const QgsExpression::NodeBinaryOperator *>( node )->op() )
|
||||
switch ( static_cast<const QgsExpressionNodeBinaryOperator *>( node )->op() )
|
||||
{
|
||||
case QgsExpression::boPow:
|
||||
case QgsExpression::boRegexp:
|
||||
case QgsExpressionNodeBinaryOperator::boPow:
|
||||
case QgsExpressionNodeBinaryOperator::boRegexp:
|
||||
return Fail; //not supported by SQLite
|
||||
|
||||
default:
|
||||
|
@ -42,7 +42,7 @@ class CORE_EXPORT QgsSQLiteExpressionCompiler : public QgsSqlExpressionCompiler
|
||||
|
||||
protected:
|
||||
|
||||
virtual Result compileNode( const QgsExpression::Node *node, QString &str ) override;
|
||||
virtual Result compileNode( const QgsExpressionNode *node, QString &str ) override;
|
||||
virtual QString quotedIdentifier( const QString &identifier ) override;
|
||||
virtual QString quotedValue( const QVariant &value, bool &ok ) override;
|
||||
virtual QString sqlFunctionFromFunctionName( const QString &fnName ) const override;
|
||||
|
@ -650,7 +650,7 @@ class CORE_EXPORT QgsSQLStatement
|
||||
public:
|
||||
//! Constructor
|
||||
NodeSelect( const QList<NodeTableDef *> &tableList, const QList<NodeSelectedColumn *> &columns, bool distinct ) : mTableList( tableList ), mColumns( columns ), mDistinct( distinct ), mWhere( nullptr ) {}
|
||||
virtual ~NodeSelect() { qDeleteAll( mTableList ); qDeleteAll( mColumns ); qDeleteAll( mJoins ); delete mWhere; qDeleteAll( mOrderBy ); }
|
||||
virtual ~NodeSelect();
|
||||
|
||||
//! Set joins
|
||||
void setJoins( const QList<NodeJoin *> &joins ) { qDeleteAll( mJoins ); mJoins = joins; }
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "qgscurve.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsexpressionfieldbuffer.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsfeaturerequest.h"
|
||||
#include "qgsfields.h"
|
||||
@ -2610,7 +2611,7 @@ QString QgsVectorLayer::displayField() const
|
||||
QgsExpression exp( mDisplayExpression );
|
||||
if ( exp.isField() )
|
||||
{
|
||||
return static_cast<const QgsExpression::NodeColumnRef *>( exp.rootNode() )->name();
|
||||
return static_cast<const QgsExpressionNodeColumnRef *>( exp.rootNode() )->name();
|
||||
}
|
||||
|
||||
return QString();
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "qgssymbol.h"
|
||||
#include "qgscolorramp.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionnode.h"
|
||||
#include "qgspainteffect.h"
|
||||
#include "qgspainteffectregistry.h"
|
||||
#include "qgsapplication.h"
|
||||
@ -3768,10 +3769,10 @@ QgsExpression *QgsSymbolLayerUtils::fieldOrExpressionToExpression( const QString
|
||||
|
||||
QString QgsSymbolLayerUtils::fieldOrExpressionFromExpression( QgsExpression *expression )
|
||||
{
|
||||
const QgsExpression::Node *n = expression->rootNode();
|
||||
const QgsExpressionNode *n = expression->rootNode();
|
||||
|
||||
if ( n && n->nodeType() == QgsExpression::ntColumnRef )
|
||||
return static_cast<const QgsExpression::NodeColumnRef *>( n )->name();
|
||||
if ( n && n->nodeType() == QgsExpressionNode::ntColumnRef )
|
||||
return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
|
||||
|
||||
return expression->expression();
|
||||
}
|
||||
|
@ -746,35 +746,34 @@ INCLUDE_DIRECTORIES(SYSTEM
|
||||
${QT_QTUITOOLS_INCLUDE_DIR}
|
||||
)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/symbology-ng
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/attributetable
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/auth
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/editorwidgets
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/editorwidgets/core
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/layertree
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/locator
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/effects
|
||||
${CMAKE_SOURCE_DIR}/src/gui
|
||||
${CMAKE_SOURCE_DIR}/src/gui/symbology-ng
|
||||
${CMAKE_SOURCE_DIR}/src/gui/attributetable
|
||||
${CMAKE_SOURCE_DIR}/src/gui/auth
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets
|
||||
${CMAKE_SOURCE_DIR}/src/gui/editorwidgets/core
|
||||
${CMAKE_SOURCE_DIR}/src/gui/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/gui/effects
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
${CMAKE_SOURCE_DIR}/src/core/locator
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/providers/memory
|
||||
${CMAKE_SOURCE_DIR}/src/core/raster
|
||||
${CMAKE_SOURCE_DIR}/src/core/scalebar
|
||||
${CMAKE_SOURCE_DIR}/src/core/symbology-ng
|
||||
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/native
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/gui
|
||||
${CMAKE_BINARY_DIR}/src/native
|
||||
../core
|
||||
../core/annotations
|
||||
../core/auth
|
||||
../core/composer
|
||||
../core/fieldformatter
|
||||
../core/geometry
|
||||
../core/layertree
|
||||
../core/metadata
|
||||
../core/providers/memory
|
||||
../core/raster
|
||||
../core/scalebar
|
||||
../core/symbology-ng
|
||||
../core/effects
|
||||
../core/metadata
|
||||
../native
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ui
|
||||
)
|
||||
INCLUDE_DIRECTORIES(SYSTEM
|
||||
${QCA_INCLUDE_DIR}
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgsfieldformatterregistry.h"
|
||||
#include "qgsgui.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <limits>
|
||||
@ -803,7 +805,7 @@ void QgsAttributeTableModel::prefetchSortData( const QString &expressionString )
|
||||
|
||||
if ( mSortCacheExpression.isField() )
|
||||
{
|
||||
QString fieldName = static_cast<const QgsExpression::NodeColumnRef *>( mSortCacheExpression.rootNode() )->name();
|
||||
QString fieldName = static_cast<const QgsExpressionNodeColumnRef *>( mSortCacheExpression.rootNode() )->name();
|
||||
mSortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName );
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "qgsexpressionbuilderwidget.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsexpressionfunction.h"
|
||||
#include "qgsmessageviewer.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgspythonrunner.h"
|
||||
@ -476,7 +477,7 @@ void QgsExpressionBuilderWidget::updateFunctionTree()
|
||||
int count = QgsExpression::functionCount();
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
QgsExpression::Function *func = QgsExpression::Functions()[i];
|
||||
QgsExpressionFunction *func = QgsExpression::Functions()[i];
|
||||
QString name = func->name();
|
||||
if ( name.startsWith( '_' ) ) // do not display private functions
|
||||
continue;
|
||||
@ -596,7 +597,7 @@ void QgsExpressionBuilderWidget::loadExpressionContext()
|
||||
QStringList contextFunctions = mExpressionContext.functionNames();
|
||||
Q_FOREACH ( const QString &functionName, contextFunctions )
|
||||
{
|
||||
QgsExpression::Function *func = mExpressionContext.function( functionName );
|
||||
QgsExpressionFunction *func = mExpressionContext.function( functionName );
|
||||
QString name = func->name();
|
||||
if ( name.startsWith( '_' ) ) // do not display private functions
|
||||
continue;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <qgsbabelformat.h>
|
||||
#include "qgsbabelformat.h"
|
||||
|
||||
|
||||
class QgsGPSDevice : public QgsBabelFormat
|
||||
|
@ -17,6 +17,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsdb2expressioncompiler.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
QgsDb2ExpressionCompiler::QgsDb2ExpressionCompiler( QgsDb2FeatureSource *source )
|
||||
@ -26,16 +27,16 @@ QgsDb2ExpressionCompiler::QgsDb2ExpressionCompiler( QgsDb2FeatureSource *source
|
||||
|
||||
}
|
||||
|
||||
QString nodeType( const QgsExpression::Node *node )
|
||||
QString nodeType( const QgsExpressionNode *node )
|
||||
{
|
||||
QString opString = QStringLiteral( "?" );
|
||||
if ( node->nodeType() == QgsExpression::ntUnaryOperator ) opString = QStringLiteral( "ntUnaryOperator" );
|
||||
if ( node->nodeType() == QgsExpression::ntBinaryOperator ) opString = QStringLiteral( "ntBinaryOperator" );
|
||||
if ( node->nodeType() == QgsExpression::ntInOperator ) opString = QStringLiteral( "ntInOperator" );
|
||||
if ( node->nodeType() == QgsExpression::ntFunction ) opString = QStringLiteral( "ntFunction" );
|
||||
if ( node->nodeType() == QgsExpression::ntLiteral ) opString = QStringLiteral( "ntLiteral" );
|
||||
if ( node->nodeType() == QgsExpression::ntColumnRef ) opString = QStringLiteral( "ntColumnRef" );
|
||||
if ( node->nodeType() == QgsExpression::ntCondition ) opString = QStringLiteral( "ntCondition" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntUnaryOperator ) opString = QStringLiteral( "ntUnaryOperator" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntBinaryOperator ) opString = QStringLiteral( "ntBinaryOperator" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntInOperator ) opString = QStringLiteral( "ntInOperator" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntFunction ) opString = QStringLiteral( "ntFunction" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntLiteral ) opString = QStringLiteral( "ntLiteral" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntColumnRef ) opString = QStringLiteral( "ntColumnRef" );
|
||||
if ( node->nodeType() == QgsExpressionNode::ntCondition ) opString = QStringLiteral( "ntCondition" );
|
||||
QString result = QStringLiteral( "%1 - " ).arg( node->nodeType() ) + opString;
|
||||
return result;
|
||||
|
||||
@ -51,12 +52,12 @@ QString resultType( QgsSqlExpressionCompiler::Result result )
|
||||
|
||||
}
|
||||
|
||||
QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const QgsExpression::Node *node, QString &result )
|
||||
QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const QgsExpressionNode *node, QString &result )
|
||||
{
|
||||
QgsDebugMsg( QString( "nodeType: %1" ).arg( nodeType( node ) ) );
|
||||
if ( node->nodeType() == QgsExpression::ntColumnRef )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
const QgsExpression::NodeColumnRef *n( static_cast<const QgsExpression::NodeColumnRef *>( node ) );
|
||||
const QgsExpressionNodeColumnRef *n( static_cast<const QgsExpressionNodeColumnRef *>( node ) );
|
||||
QgsDebugMsg( QString( "column ref node: " ) + n->dump() );
|
||||
// TODO - consider escaped names - not sure how to handle
|
||||
QString upperName = n->name().toUpper();
|
||||
@ -73,7 +74,7 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
}
|
||||
// Seemed necessary in initial Python testing but can't identify failing case now
|
||||
#if 0
|
||||
if ( node->nodeType() == QgsExpression::ntLiteral )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntLiteral )
|
||||
{
|
||||
const QgsExpression::NodeLiteral *n = static_cast<const QgsExpression::NodeLiteral *>( node );
|
||||
|
||||
@ -103,13 +104,13 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
|
||||
}
|
||||
#endif
|
||||
if ( node->nodeType() == QgsExpression::ntUnaryOperator )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntUnaryOperator )
|
||||
{
|
||||
const QgsExpression::NodeUnaryOperator *n = static_cast<const QgsExpression::NodeUnaryOperator *>( node );
|
||||
const QgsExpressionNodeUnaryOperator *n = static_cast<const QgsExpressionNodeUnaryOperator *>( node );
|
||||
Result rr = Fail;
|
||||
switch ( n->op() )
|
||||
{
|
||||
case QgsExpression::uoNot:
|
||||
case QgsExpressionNodeUnaryOperator::uoNot:
|
||||
rr = compileNode( n->operand(), result );
|
||||
if ( "NULL" == result.toUpper() )
|
||||
{
|
||||
@ -121,14 +122,14 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
QgsDebugMsg( QString( "NOT; result: %1; right: %2" ).arg( resultType( rr ), result ) );
|
||||
return rr;
|
||||
|
||||
case QgsExpression::uoMinus:
|
||||
case QgsExpressionNodeUnaryOperator::uoMinus:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( node->nodeType() == QgsExpression::ntBinaryOperator )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntBinaryOperator )
|
||||
{
|
||||
const QgsExpression::NodeBinaryOperator *bin( static_cast<const QgsExpression::NodeBinaryOperator *>( node ) );
|
||||
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
|
||||
QString left, right;
|
||||
|
||||
Result lr = compileNode( bin->opLeft(), left );
|
||||
@ -141,33 +142,33 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
// NULL can not appear on the left, only as part of IS NULL or IS NOT NULL
|
||||
if ( "NULL" == left.toUpper() ) return Fail;
|
||||
// NULL can only be on the right for IS and IS NOT
|
||||
if ( "NULL" == right.toUpper() && ( bin->op() != QgsExpression::boIs && bin->op() != QgsExpression::boIsNot ) )
|
||||
if ( "NULL" == right.toUpper() && ( bin->op() != QgsExpressionNodeBinaryOperator::boIs && bin->op() != QgsExpressionNodeBinaryOperator::boIsNot ) )
|
||||
return Fail;
|
||||
|
||||
switch ( bin->op() )
|
||||
{
|
||||
case QgsExpression::boMod:
|
||||
case QgsExpressionNodeBinaryOperator::boMod:
|
||||
result = QStringLiteral( "MOD(%1,%2)" ).arg( left, right );
|
||||
compileResult = ( lr == Partial || rr == Partial ) ? Partial : Complete;
|
||||
QgsDebugMsg( QString( "MOD compile status: %1" ).arg( compileResult ) + "; " + result );
|
||||
return compileResult;
|
||||
|
||||
case QgsExpression::boPow:
|
||||
case QgsExpressionNodeBinaryOperator::boPow:
|
||||
result = QStringLiteral( "power(%1,%2)" ).arg( left, right );
|
||||
compileResult = ( lr == Partial || rr == Partial ) ? Partial : Complete;
|
||||
QgsDebugMsg( QString( "POWER compile status: %1" ).arg( compileResult ) + "; " + result );
|
||||
return compileResult;
|
||||
|
||||
case QgsExpression::boRegexp:
|
||||
case QgsExpressionNodeBinaryOperator::boRegexp:
|
||||
return Fail; //not supported, regexp syntax is too different to Qt
|
||||
|
||||
case QgsExpression::boConcat:
|
||||
case QgsExpressionNodeBinaryOperator::boConcat:
|
||||
result = QStringLiteral( "%1 || %2" ).arg( left, right );
|
||||
compileResult = ( lr == Partial || rr == Partial ) ? Partial : Complete;
|
||||
QgsDebugMsg( QString( "CONCAT compile status: %1" ).arg( compileResult ) + "; " + result );
|
||||
return compileResult;
|
||||
|
||||
case QgsExpression::boILike:
|
||||
case QgsExpressionNodeBinaryOperator::boILike:
|
||||
QgsDebugMsg( "ILIKE is not supported by DB2" );
|
||||
return Fail;
|
||||
/*
|
||||
@ -177,7 +178,7 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
return compileResult;
|
||||
*/
|
||||
|
||||
case QgsExpression::boNotILike:
|
||||
case QgsExpressionNodeBinaryOperator::boNotILike:
|
||||
QgsDebugMsg( "NOT ILIKE is not supported by DB2" );
|
||||
return Fail;
|
||||
/*
|
||||
@ -188,10 +189,10 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
*/
|
||||
|
||||
// We only support IS NULL if the operand on the left is a column
|
||||
case QgsExpression::boIs:
|
||||
case QgsExpressionNodeBinaryOperator::boIs:
|
||||
if ( "NULL" == right.toUpper() )
|
||||
{
|
||||
if ( bin->opLeft()->nodeType() != QgsExpression::ntColumnRef )
|
||||
if ( bin->opLeft()->nodeType() != QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
QgsDebugMsg( "Failing IS NULL with non-column on left: " + left );
|
||||
return Fail;
|
||||
@ -199,10 +200,10 @@ QgsSqlExpressionCompiler::Result QgsDb2ExpressionCompiler::compileNode( const Qg
|
||||
}
|
||||
break;
|
||||
// We only support IS NULL if the operand on the left is a column
|
||||
case QgsExpression::boIsNot:
|
||||
case QgsExpressionNodeBinaryOperator::boIsNot:
|
||||
if ( "NULL" == right.toUpper() )
|
||||
{
|
||||
if ( bin->opLeft()->nodeType() != QgsExpression::ntColumnRef )
|
||||
if ( bin->opLeft()->nodeType() != QgsExpressionNode::ntColumnRef )
|
||||
{
|
||||
QgsDebugMsg( "Failing IS NOT NULL with non-column on left: " + left );
|
||||
return Fail;
|
||||
|
@ -29,7 +29,7 @@ class QgsDb2ExpressionCompiler : public QgsSqlExpressionCompiler
|
||||
explicit QgsDb2ExpressionCompiler( QgsDb2FeatureSource *source );
|
||||
|
||||
protected:
|
||||
virtual Result compileNode( const QgsExpression::Node *node, QString &result ) override;
|
||||
virtual Result compileNode( const QgsExpressionNode *node, QString &result ) override;
|
||||
virtual QString quotedValue( const QVariant &value, bool &ok ) override;
|
||||
|
||||
};
|
||||
|
@ -16,9 +16,11 @@ SET (GPX_MOC_HDRS
|
||||
# Build
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
../../core
|
||||
../../core/geometry
|
||||
../../core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/gui
|
||||
)
|
||||
|
@ -14,6 +14,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmssqlexpressioncompiler.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
QgsMssqlExpressionCompiler::QgsMssqlExpressionCompiler( QgsMssqlFeatureSource *source )
|
||||
: QgsSqlExpressionCompiler( source->mFields,
|
||||
@ -24,9 +25,9 @@ QgsMssqlExpressionCompiler::QgsMssqlExpressionCompiler( QgsMssqlFeatureSource *s
|
||||
|
||||
QgsSqlExpressionCompiler::Result QgsMssqlExpressionCompiler::compileNode( const QgsExpression::Node *node, QString &result )
|
||||
{
|
||||
if ( node->nodeType() == QgsExpression::ntBinaryOperator )
|
||||
if ( node->nodeType() == QgsExpressionNode::ntBinaryOperator )
|
||||
{
|
||||
const QgsExpression::NodeBinaryOperator *bin( static_cast<const QgsExpression::NodeBinaryOperator *>( node ) );
|
||||
const QgsExpressionNodeBinaryOperator *bin( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
|
||||
QString op1, op2;
|
||||
|
||||
Result result1 = compileNode( bin->opLeft(), op1 );
|
||||
@ -36,14 +37,14 @@ QgsSqlExpressionCompiler::Result QgsMssqlExpressionCompiler::compileNode( const
|
||||
|
||||
switch ( bin->op() )
|
||||
{
|
||||
case QgsExpression::boPow:
|
||||
case QgsExpressionNodeBinaryOperator::boPow:
|
||||
result = QStringLiteral( "power(%1,%2)" ).arg( op1, op2 );
|
||||
return result1 == Partial || result2 == Partial ? Partial : Complete;
|
||||
|
||||
case QgsExpression::boRegexp:
|
||||
case QgsExpressionNodeBinaryOperator::boRegexp:
|
||||
return Fail; //not supported, regexp syntax is too different to Qt
|
||||
|
||||
case QgsExpression::boConcat:
|
||||
case QgsExpressionNodeBinaryOperator::boConcat:
|
||||
result = QStringLiteral( "%1 + %2" ).arg( op1, op2 );
|
||||
return result1 == Partial || result2 == Partial ? Partial : Complete;
|
||||
|
||||
|
@ -9,11 +9,12 @@ SET(OGR_MOC_HDRS qgsogrprovider.h qgsogrdataitems.h qgsogrconnpool.h)
|
||||
QT5_WRAP_CPP(OGR_MOC_SRCS ${OGR_MOC_HDRS})
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
.
|
||||
../../core
|
||||
../../core/geometry
|
||||
../../core/metadata
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../core/symbology-ng
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/symbology-ng
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/gui
|
||||
)
|
||||
|
@ -49,18 +49,18 @@ QgsSqlExpressionCompiler::Result QgsOgrExpressionCompiler::compileNode( const Qg
|
||||
{
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntBinaryOperator:
|
||||
case QgsExpressionNode::ntBinaryOperator:
|
||||
{
|
||||
switch ( static_cast<const QgsExpression::NodeBinaryOperator *>( node )->op() )
|
||||
{
|
||||
case QgsExpression::boILike:
|
||||
case QgsExpression::boNotILike:
|
||||
case QgsExpressionNodeBinaryOperator::boILike:
|
||||
case QgsExpressionNodeBinaryOperator::boNotILike:
|
||||
return Fail; //disabled until https://trac.osgeo.org/gdal/ticket/5132 is fixed
|
||||
|
||||
case QgsExpression::boMod:
|
||||
case QgsExpression::boConcat:
|
||||
case QgsExpression::boPow:
|
||||
case QgsExpression::boRegexp:
|
||||
case QgsExpressionNodeBinaryOperator::boMod:
|
||||
case QgsExpressionNodeBinaryOperator::boConcat:
|
||||
case QgsExpressionNodeBinaryOperator::boPow:
|
||||
case QgsExpressionNodeBinaryOperator::boRegexp:
|
||||
return Fail; //not supported by OGR
|
||||
|
||||
default:
|
||||
@ -69,15 +69,15 @@ QgsSqlExpressionCompiler::Result QgsOgrExpressionCompiler::compileNode( const Qg
|
||||
}
|
||||
}
|
||||
|
||||
case QgsExpression::ntFunction:
|
||||
case QgsExpression::ntCondition:
|
||||
case QgsExpressionNode::ntFunction:
|
||||
case QgsExpressionNode::ntCondition:
|
||||
//not support by OGR
|
||||
return Fail;
|
||||
|
||||
case QgsExpression::ntUnaryOperator:
|
||||
case QgsExpression::ntColumnRef:
|
||||
case QgsExpression::ntInOperator:
|
||||
case QgsExpression::ntLiteral:
|
||||
case QgsExpressionNode::ntUnaryOperator:
|
||||
case QgsExpressionNode::ntColumnRef:
|
||||
case QgsExpressionNode::ntInOperator:
|
||||
case QgsExpressionNode::ntLiteral:
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "qgspostgresexpressioncompiler.h"
|
||||
#include "qgssqlexpressioncompiler.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
QgsPostgresExpressionCompiler::QgsPostgresExpressionCompiler( QgsPostgresFeatureSource *source )
|
||||
: QgsSqlExpressionCompiler( source->mFields, QgsSqlExpressionCompiler::IntegerDivisionResultsInInteger )
|
||||
|
@ -15,12 +15,13 @@ email : hugo dot mercier at oslandia dot com
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <qgsvirtuallayerfeatureiterator.h>
|
||||
#include <qgsmessagelog.h>
|
||||
#include <qgsgeometry.h>
|
||||
#include <stdexcept>
|
||||
#include "qgsvirtuallayerfeatureiterator.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsvirtuallayerblob.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
static QString quotedColumn( QString name )
|
||||
{
|
||||
return "\"" + name.replace( QLatin1String( "\"" ), QLatin1String( "\"\"" ) ) + "\"";
|
||||
|
@ -18,8 +18,9 @@ email : hugo dot mercier at oslandia dot com
|
||||
#define QGSVIRTUALLAYER_FEATURE_ITERATOR_H
|
||||
|
||||
|
||||
#include <qgsvirtuallayerprovider.h>
|
||||
#include <qgsfeatureiterator.h>
|
||||
#include "qgsvirtuallayerprovider.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
|
||||
#include <memory>
|
||||
#include <QPointer>
|
||||
|
||||
|
@ -727,7 +727,7 @@ void qgisFunctionWrapper( sqlite3_context *ctxt, int nArgs, sqlite3_value **args
|
||||
// geometries are converted between spatialite and QgsGeometry
|
||||
// other data types (datetime mainly) are represented as BLOBs thanks to QVariant serializing functions
|
||||
|
||||
QgsExpression::Function *foo = reinterpret_cast<QgsExpression::Function *>( sqlite3_user_data( ctxt ) );
|
||||
QgsExpressionFunction *foo = reinterpret_cast<QgsExpressionFunction *>( sqlite3_user_data( ctxt ) );
|
||||
|
||||
QVariantList variants;
|
||||
for ( int i = 0; i < nArgs; i++ )
|
||||
@ -849,7 +849,7 @@ void registerQgisFunctions( sqlite3 *db )
|
||||
QStringList reservedFunctions;
|
||||
reservedFunctions << QStringLiteral( "left" ) << QStringLiteral( "right" ) << QStringLiteral( "union" );
|
||||
// register QGIS expression functions
|
||||
Q_FOREACH ( QgsExpression::Function *foo, QgsExpression::Functions() )
|
||||
Q_FOREACH ( QgsExpressionFunction *foo, QgsExpression::Functions() )
|
||||
{
|
||||
if ( foo->usesGeometry( nullptr ) || foo->lazyEval() )
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/src/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/composer
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/metadata
|
||||
${CMAKE_SOURCE_DIR}/src/core/effects
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
#include <qgsapplication.h>
|
||||
//header for class being tested
|
||||
#include <qgsexpression.h>
|
||||
#include <qgsfeature.h>
|
||||
#include "qgsexpression.h"
|
||||
#include "qgsfeature.h"
|
||||
#include "qgsfeatureiterator.h"
|
||||
#include <qgsfeaturerequest.h>
|
||||
#include <qgsgeometry.h>
|
||||
#include <qgsrenderchecker.h>
|
||||
#include "qgsfeaturerequest.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsrenderchecker.h"
|
||||
#include "qgsexpressioncontext.h"
|
||||
#include "qgsrelationmanager.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
@ -32,6 +32,7 @@
|
||||
#include "qgsdistancearea.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsexpressionnodeimpl.h"
|
||||
|
||||
static void _parseAndEvalExpr( int arg )
|
||||
{
|
||||
@ -1211,12 +1212,6 @@ class TestQgsExpression: public QObject
|
||||
run_evaluation_test( exp4, evalError, result );
|
||||
}
|
||||
|
||||
void eval_precedence()
|
||||
{
|
||||
QCOMPARE( QgsExpression::BINARY_OPERATOR_TEXT[QgsExpression::boDiv], "/" );
|
||||
QCOMPARE( QgsExpression::BINARY_OPERATOR_TEXT[QgsExpression::boConcat], "||" );
|
||||
}
|
||||
|
||||
void eval_columns()
|
||||
{
|
||||
QgsFields fields;
|
||||
|
@ -114,7 +114,7 @@ class TestQgsExpressionContext : public QObject
|
||||
/**
|
||||
* This function is not static, it's value changes with every invocation.
|
||||
*/
|
||||
virtual bool isStatic( const QgsExpression::NodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override
|
||||
virtual bool isStatic( const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context ) const override
|
||||
{
|
||||
Q_UNUSED( node )
|
||||
Q_UNUSED( parent )
|
||||
|
Loading…
x
Reference in New Issue
Block a user