26#include <QRegularExpression>
28const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
32 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
33 "+",
"-",
"*",
"/",
"//",
"%",
"^",
37const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
46 const QList< QgsExpressionNode * > nodeList = mList->list();
48 needs |= n->needsGeometry();
59 mList.append( node->
node );
60 mNameList.append( cleanNamedNodeName( node->
name ) );
61 mHasNamedNodes =
true;
70 nl->mList.append( node->clone() );
72 nl->mNameList = mNameList;
83 if ( !first ) msg += QLatin1String(
", " );
90QString QgsExpressionNode::NodeList::cleanNamedNodeName(
const QString &name )
92 QString cleaned = name.toLower();
95 if ( cleaned == QLatin1String(
"geom" ) )
96 cleaned = QStringLiteral(
"geometry" );
97 else if ( cleaned == QLatin1String(
"val" ) )
98 cleaned = QStringLiteral(
"value" );
99 else if ( cleaned == QLatin1String(
"geometry a" ) )
100 cleaned = QStringLiteral(
"geometry1" );
101 else if ( cleaned == QLatin1String(
"geometry b" ) )
102 cleaned = QStringLiteral(
"geometry2" );
103 else if ( cleaned == QLatin1String(
"i" ) )
104 cleaned = QStringLiteral(
"vertex" );
114 QVariant val = mOperand->eval( parent, context );
121 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
123 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
127 if ( QgsExpressionUtils::isIntSafe( val ) )
128 return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
129 else if ( QgsExpressionUtils::isDoubleSafe( val ) )
130 return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
144 return mOperand->prepare( parent, context );
150 return QStringLiteral(
"%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
152 return QStringLiteral(
"%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
158 return QSet< QString >();
160 return mOperand->referencedColumns();
165 return mOperand->referencedVariables();
170 return mOperand->referencedFunctions();
175 QList<const QgsExpressionNode *> lst;
177 lst += mOperand->nodes();
183 return mOperand->needsGeometry();
195 return mOperand->
isStatic( parent, context );
200 return UNARY_OPERATOR_TEXT[mOp];
251QVariant QgsExpressionNodeBinaryOperator::compareNonNullValues(
QgsExpression *parent,
const QgsExpressionContext *,
const QVariant &vL,
const QVariant &vR, BinaryOperator op )
253 if ( ( vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime ) )
255 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
257 QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
264 dL.setTimeSpec( Qt::UTC );
265 dR.setTimeSpec( Qt::UTC );
267 return compareOp<qint64>( dR.msecsTo( dL ), op ) ? TVL_True : TVL_False;
269 else if ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate ) )
271 const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
273 const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
275 return compareOp<qint64>( dR.daysTo( dL ), op ) ? TVL_True : TVL_False;
277 else if ( ( vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime ) )
279 const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
281 const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
283 return compareOp<int>( dR.msecsTo( dL ), op ) ? TVL_True : TVL_False;
285 else if ( ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) &&
286 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
290 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
292 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
294 return compareOp< double >( fL - fR, op ) ? TVL_True : TVL_False;
297 else if ( vL.userType() == QMetaType::Type::Bool || vR.userType() == QMetaType::Type::Bool )
319 const bool vLBool = vL.toBool();
320 const bool vRBool = vR.toBool();
324 return vLBool == vRBool ? TVL_True : TVL_False;
326 return vLBool != vRBool ? TVL_True : TVL_False;
328 return vLBool < vRBool ? TVL_True : TVL_False;
330 return vLBool <= vRBool ? TVL_True : TVL_False;
332 return vLBool > vRBool ? TVL_True : TVL_False;
334 return vLBool >= vRBool ? TVL_True : TVL_False;
359 else if ( vL.userType() == qMetaTypeId< QgsInterval>() && vR.userType() == qMetaTypeId< QgsInterval>() )
361 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
363 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
365 return compareOp< double >( fL - fR, op ) ? TVL_True : TVL_False;
370 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
372 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
374 int diff = QString::compare( sL, sR );
375 return compareOp<int>( diff, op ) ? TVL_True : TVL_False;
381 QVariant vL = mOpLeft->eval( parent, context );
384 if ( mOp == boAnd || mOp == boOr )
386 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
388 if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
390 if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
394 QVariant vR = mOpRight->eval( parent, context );
400 if ( vL.userType() == QMetaType::Type::QString && vR.userType() == QMetaType::Type::QString )
402 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
404 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
406 return QVariant( sL + sR );
415 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
417 else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
420 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
422 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
425 if ( mOp == boMod && iR == 0 )
428 return QVariant( computeInt( iL, iR ) );
430 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
432 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
434 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
436 if ( mOp == boDiv || mOp == boMul || mOp == boMod )
438 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
441 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
443 else if ( mOp == boPlus && ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QTime ) ||
444 ( vR.userType() == QMetaType::Type::QDate && vL.userType() == QMetaType::Type::QTime ) ) )
446 QDate date = QgsExpressionUtils::getDateValue( vL.userType() == QMetaType::Type::QDate ? vL : vR, parent );
448 QTime time = QgsExpressionUtils::getTimeValue( vR.userType() == QMetaType::Type::QTime ? vR : vL, parent );
450 QDateTime dt = QDateTime( date, time );
451 return QVariant( dt );
453 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate )
455 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
457 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
459 return date1 - date2;
461 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime )
463 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
465 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
467 return time1 - time2;
469 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime )
471 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
473 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
480 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
482 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
484 if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
486 return QVariant( computeDouble( fL, fR ) );
492 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
494 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
498 return QVariant( qlonglong( std::floor( fL / fR ) ) );
501 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
505 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
507 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
509 return QVariant( std::pow( fL, fR ) );
514 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
516 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
521 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
523 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
532 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
536 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
539 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
543 QVariantList lL = vL.toList();
544 QVariantList lR = vR.toList();
545 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
547 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
550 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
560 return QgsExpressionUtils::isNull( lR.at( i ) );
563 return QgsExpressionUtils::isNull( lL.at( i ) );
573 QVariant eq = eqNode.
eval( parent, context );
575 if ( eq == TVL_False )
579 QVariant v = node.
eval( parent, context );
589 return lL.length() == lR.length();
591 return lL.length() != lR.length();
593 return lL.length() < lR.length();
595 return lL.length() > lR.length();
597 return lL.length() <= lR.length();
599 return lL.length() >= lR.length();
607 return compareNonNullValues( parent, context, vL, vR, mOp );
613 const bool vLNull = QgsExpressionUtils::isNull( vL );
614 const bool vRNull = QgsExpressionUtils::isNull( vR );
615 if ( vLNull && vRNull )
616 return ( mOp == boIs ? TVL_True : TVL_False );
617 else if ( vLNull || vRNull )
618 return ( mOp == boIs ? TVL_False : TVL_True );
621 return compareNonNullValues( parent, context, vL, vR, mOp == boIs ? boEQ : boNE );
630 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
634 QString str = QgsExpressionUtils::getStringValue( vL, parent );
636 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
640 if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike )
644 if ( esc_regexp.startsWith(
'%' ) )
646 esc_regexp.replace( 0, 1, QStringLiteral(
".*" ) );
648 const thread_local QRegularExpression rx1( QStringLiteral(
"[^\\\\](%)" ) );
650 while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
652 esc_regexp.replace( pos + 1, 1, QStringLiteral(
".*" ) );
655 const thread_local QRegularExpression rx2( QStringLiteral(
"\\\\%" ) );
656 esc_regexp.replace( rx2, QStringLiteral(
"%" ) );
657 if ( esc_regexp.startsWith(
'_' ) )
659 esc_regexp.replace( 0, 1, QStringLiteral(
"." ) );
661 const thread_local QRegularExpression rx3( QStringLiteral(
"[^\\\\](_)" ) );
663 while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
665 esc_regexp.replace( pos + 1, 1,
'.' );
668 esc_regexp.replace( QLatin1String(
"\\\\_" ), QLatin1String(
"_" ) );
670 matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp == boLike || mOp == boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption ).match( str ).hasMatch();
674 matches = QRegularExpression( regexp ).match( str ).hasMatch();
677 if ( mOp == boNotLike || mOp == boNotILike )
682 return matches ? TVL_True : TVL_False;
686 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
690 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
692 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
694 return QVariant( sL + sR );
701qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
721QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d,
QgsInterval *i )
726 return d.addSecs( i->
seconds() );
728 return d.addSecs( -i->
seconds() );
735double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
748 return std::fmod( x, y );
768 QMap<QString, QgsExpressionNode::NodeList> orValuesMap;
769 QList<QString> orFieldNames;
776 if ( op->op() != boOr && op->op() != boEQ )
781 if ( op->op() == boEQ )
786 const QString fieldName = op->opLeft()->dump();
787 if ( !orValuesMap.contains( fieldName ) )
789 orFieldNames.append( fieldName );
792 orValuesMap[fieldName].append( op->opRight()->clone() );
797 const QString fieldName = op->opRight()->dump();
798 if ( !orValuesMap.contains( fieldName ) )
800 orFieldNames.append( fieldName );
803 orValuesMap[fieldName].append( op->opLeft()->clone() );
809 if ( visitOrNodes( op->opLeft() ) && visitOrNodes( op->opRight() ) )
822 const QString fieldName = inOp->node()->dump();
825 const auto nodes = inOp->list()->list();
826 for (
const auto &valueNode : std::as_const(
nodes ) )
834 if ( !orValuesMap.contains( fieldName ) )
836 orFieldNames.append( fieldName );
837 orValuesMap.insert( fieldName, *inOp->list()->clone() );
841 for (
const auto &valueNode : std::as_const(
nodes ) )
843 orValuesMap[fieldName].append( valueNode->clone() );
854 if ( visitOrNodes(
this ) && ! orValuesMap.empty() )
857 std::unique_ptr<QgsExpressionNode> currentNode;
858 for (
const auto &fieldName : std::as_const( orFieldNames ) )
860 auto orValuesIt = orValuesMap.find( fieldName );
861 if ( orValuesIt.value().count() == 1 )
863 auto eqNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boEQ,
new QgsExpressionNodeColumnRef( fieldName ), orValuesIt.value().at( 0 )->
clone() );
866 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), eqNode.release() );
870 currentNode = std::move( eqNode );
878 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), inNode.release() );
882 currentNode = std::move( inNode );
896 bool resL = mOpLeft->prepare( parent, context );
897 bool resR = mOpRight->prepare( parent, context );
943 Q_ASSERT(
false &&
"unexpected binary operator" );
979 Q_ASSERT(
false &&
"unexpected binary operator" );
989 QString rdump( mOpRight->dump() );
994 rdump.prepend(
'(' ).append(
')' );
998 if ( leftAssociative() )
1000 fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
1001 fmt += QLatin1String(
" %2 " );
1002 fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
1006 fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
1007 fmt += QLatin1String(
" %2 " );
1008 fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
1011 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
1017 return QSet< QString >();
1019 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
1024 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
1029 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
1034 QList<const QgsExpressionNode *> lst;
1036 lst += mOpLeft->nodes() + mOpRight->nodes();
1042 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
1054 const bool leftStatic = mOpLeft->
isStatic( parent, context );
1055 const bool rightStatic = mOpRight->isStatic( parent, context );
1057 if ( leftStatic && rightStatic )
1069 mOpLeft->prepare( parent, context );
1070 if ( mOpLeft->hasCachedStaticValue() )
1072 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1073 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1081 else if ( rightStatic )
1083 mOpRight->prepare( parent, context );
1084 if ( mOpRight->hasCachedStaticValue() )
1086 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1087 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1105 mOpLeft->prepare( parent, context );
1106 if ( mOpLeft->hasCachedStaticValue() )
1108 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1109 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1117 else if ( rightStatic )
1119 mOpRight->prepare( parent, context );
1120 if ( mOpRight->hasCachedStaticValue() )
1122 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1123 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1166 if ( mList->count() == 0 )
1167 return mNotIn ? TVL_True : TVL_False;
1168 QVariant v1 = mNode->eval( parent, context );
1170 if ( QgsExpressionUtils::isNull( v1 ) )
1173 bool listHasNull =
false;
1175 const QList< QgsExpressionNode * > nodeList = mList->list();
1178 QVariant v2 = n->eval( parent, context );
1180 if ( QgsExpressionUtils::isNull( v2 ) )
1186 if ( ( v1.userType() != QMetaType::Type::QString || v2.userType() != QMetaType::Type::QString ) &&
1187 QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
1191 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
1193 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
1199 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
1201 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
1203 equal = QString::compare( s1, s2 ) == 0;
1207 return mNotIn ? TVL_False : TVL_True;
1215 return mNotIn ? TVL_True : TVL_False;
1229 bool res = mNode->prepare( parent, context );
1230 const QList< QgsExpressionNode * > nodeList = mList->list();
1233 res = res && n->prepare( parent, context );
1240 return QStringLiteral(
"%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ?
"NOT" :
"", mList->dump() );
1252 if ( !mNode->isStatic( parent, context ) )
1255 const QList< QgsExpressionNode * > nodeList = mList->
list();
1258 if ( !n->isStatic( parent, context ) )
1269 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
1272 QVariant res = fd->
run( mArgs.get(), context, parent,
this );
1280 : mFnIndex( fnIndex )
1285 QMutexLocker locker( &QgsExpression::QgsExpression::sFunctionsMutex );
1288 const int functionParamsSize = functionParams.size();
1289 if ( functionParams.isEmpty() )
1292 mArgs.reset(
args );
1297 mArgs = std::make_unique<NodeList>();
1298 mArgs->reserve( functionParamsSize );
1307 mArgs = std::make_unique<NodeList>();
1308 mArgs->reserve( functionParamsSize );
1311 const QStringList argNames =
args->
names();
1312 const QList<QgsExpressionNode *> argList =
args->
list();
1315 const int argNamesSize = argNames.size();
1316 while ( idx < argNamesSize && argNames.at( idx ).isEmpty() )
1318 mArgs->append( argList.at( idx )->clone() );
1324 for ( ; idx < functionParamsSize; ++idx )
1327 int nodeIdx = argNames.indexOf( parameter.
name().toLower() );
1335 mArgs->append( argList.at( nodeIdx )->clone() );
1357 bool res = fd->
prepare(
this, parent, context );
1360 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1363 res = res && n->prepare( parent, context );
1373 return QStringLiteral(
"%1%2" ).arg( fd->
name(), fd->
name().startsWith(
'$' ) ? QString() : QStringLiteral(
"()" ) );
1375 return QStringLiteral(
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->dump() : QString() );
1381 return QSet< QString >();
1389 return functionColumns;
1393 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1396 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
1397 functionColumns.unite( n->referencedColumns() );
1401 return functionColumns;
1407 if ( fd->
name() == QLatin1String(
"var" ) )
1409 if ( !mArgs->list().isEmpty() )
1413 return QSet<QString>() << var->
value().toString();
1415 return QSet<QString>() << QString();
1419 QSet<QString> functionVariables = QSet<QString>();
1422 return functionVariables;
1424 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1427 functionVariables.unite( n->referencedVariables() );
1430 return functionVariables;
1437 QSet<QString> functions = QSet<QString>();
1438 functions.insert( fd->
name() );
1443 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1446 functions.unite( n->referencedFunctions() );
1453 QList<const QgsExpressionNode *> lst;
1458 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1468 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1471 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1473 needs |= n->needsGeometry();
1496 if ( functionParams.isEmpty() )
1503 QSet< int > providedArgs;
1504 QSet< int > handledArgs;
1507 while (
args->
names().at( idx ).isEmpty() )
1509 providedArgs << idx;
1515 for ( ; idx < functionParams.count(); ++idx )
1517 int nodeIdx =
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
1520 if ( !functionParams.at( idx ).optional() )
1522 error = QStringLiteral(
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1528 if ( providedArgs.contains( idx ) )
1530 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1534 providedArgs << idx;
1535 handledArgs << nodeIdx;
1540 const QStringList nameList =
args->
names();
1541 for (
const QString &name : nameList )
1543 if ( !name.isEmpty() && !functionParams.contains( name ) )
1548 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1550 int functionIdx = functionParams.indexOf( name );
1551 if ( providedArgs.contains( functionIdx ) )
1553 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1589 return QStringLiteral(
"NULL" );
1591 switch ( mValue.userType() )
1593 case QMetaType::Type::Int:
1594 return QString::number( mValue.toInt() );
1595 case QMetaType::Type::Double:
1597 case QMetaType::Type::LongLong:
1598 return QString::number( mValue.toLongLong() );
1599 case QMetaType::Type::QString:
1601 case QMetaType::Type::QTime:
1603 case QMetaType::Type::QDate:
1605 case QMetaType::Type::QDateTime:
1607 case QMetaType::Type::Bool:
1608 return mValue.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
1610 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1621 return QSet<QString>();
1626 return QSet<QString>();
1631 return QSet<QString>();
1636 QList<const QgsExpressionNode *> lst;
1689 parent->
setEvalErrorString( tr(
"No feature available for field '%1' evaluation" ).arg( mName ) );
1726 const thread_local QRegularExpression re( QStringLiteral(
"^[A-Za-z_\\x80-\\xff][A-Za-z0-9_\\x80-\\xff]*$" ) );
1727 const QRegularExpressionMatch match = re.match( mName );
1733 return QSet<QString>() << mName;
1738 return QSet<QString>();
1743 return QSet<QString>();
1748 QList<const QgsExpressionNode *> result;
1775 : mConditions( *conditions )
1776 , mElseExp( elseExp )
1784 qDeleteAll( mConditions );
1794 for (
WhenThen *cond : std::as_const( mConditions ) )
1796 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1797 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1799 if ( tvl == QgsExpressionUtils::True )
1801 QVariant vRes = cond->mThenExp->eval( parent, context );
1809 QVariant vElse = mElseExp->eval( parent, context );
1820 bool foundAnyNonStaticConditions =
false;
1821 for (
WhenThen *cond : std::as_const( mConditions ) )
1823 const bool res = cond->mWhenExp->prepare( parent, context )
1824 && cond->mThenExp->prepare( parent, context );
1828 foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
1829 if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
1833 if ( cond->mThenExp->hasCachedStaticValue() )
1852 const bool res = mElseExp->prepare( parent, context );
1856 if ( !foundAnyNonStaticConditions )
1859 if ( mElseExp->hasCachedStaticValue() )
1880 QString msg( QStringLiteral(
"CASE" ) );
1881 for (
WhenThen *cond : mConditions )
1883 msg += QStringLiteral(
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1886 msg += QStringLiteral(
" ELSE %1" ).arg( mElseExp->dump() );
1887 msg += QLatin1String(
" END" );
1894 return QSet< QString >();
1897 for (
WhenThen *cond : mConditions )
1899 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1903 lst += mElseExp->referencedColumns();
1911 for (
WhenThen *cond : mConditions )
1913 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1917 lst += mElseExp->referencedVariables();
1925 for (
WhenThen *cond : mConditions )
1927 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1931 lst += mElseExp->referencedFunctions();
1938 QList<const QgsExpressionNode *> lst;
1940 for (
WhenThen *cond : mConditions )
1942 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1946 lst += mElseExp->nodes();
1953 for (
WhenThen *cond : mConditions )
1955 if ( cond->mWhenExp->needsGeometry() ||
1956 cond->mThenExp->needsGeometry() )
1960 return mElseExp && mElseExp->needsGeometry();
1979 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1984 return mElseExp->isStatic( parent, context );
1992 return QSet< QString >();
1994 QSet<QString> lst( mNode->referencedColumns() );
1995 const QList< QgsExpressionNode * > nodeList = mList->list();
1997 lst.unite( n->referencedColumns() );
2003 QSet<QString> lst( mNode->referencedVariables() );
2004 const QList< QgsExpressionNode * > nodeList = mList->list();
2006 lst.unite( n->referencedVariables() );
2012 QSet<QString> lst( mNode->referencedFunctions() );
2013 const QList< QgsExpressionNode * > nodeList = mList->list();
2015 lst.unite( n->referencedFunctions() );
2021 QList<const QgsExpressionNode *> lst;
2023 const QList< QgsExpressionNode * > nodeList = mList->list();
2041 bool res = mNode->prepare( parent, context );
2042 res = res && mLowerBound->prepare( parent, context );
2043 res = res && mHigherBound->prepare( parent, context );
2049 const QVariant nodeVal = mNode->eval( parent, context );
2058 const QVariant lowBoundValue = lowBound.eval( parent, context );
2059 const bool lowBoundBool { lowBoundValue.toBool() };
2063 return QVariant( mNegate );
2067 const QVariant highBoundValue = highBound.eval( parent, context );
2074 const bool highBoundBool { highBoundValue.toBool() };
2084 return QVariant( mNegate );
2094 return QVariant( mNegate );
2097 const bool res { lowBoundBool &&highBoundBool };
2098 return mNegate ? QVariant( ! res ) : QVariant( res );
2104 return QStringLiteral(
"%1 %2 %3 AND %4" ).arg( mNode->dump(), mNegate ? QStringLiteral(
"NOT BETWEEN" ) : QStringLiteral(
"BETWEEN" ), mLowerBound->dump(), mHigherBound->dump() );
2109 QSet<QString> lst( mNode->referencedVariables() );
2110 lst.unite( mLowerBound->referencedVariables() );
2111 lst.unite( mHigherBound->referencedVariables() );
2117 QSet<QString> lst( mNode->referencedFunctions() );
2118 lst.unite( mLowerBound->referencedFunctions() );
2119 lst.unite( mHigherBound->referencedFunctions() );
2125 return {
this, mLowerBound.get(), mHigherBound.get() };
2130 QSet<QString> lst( mNode->referencedColumns() );
2131 lst.unite( mLowerBound->referencedColumns() );
2132 lst.unite( mHigherBound->referencedColumns() );
2138 if ( mNode->needsGeometry() )
2141 if ( mLowerBound->needsGeometry() )
2144 if ( mHigherBound->needsGeometry() )
2159 if ( !mNode->isStatic( parent, context ) )
2162 if ( !mLowerBound->isStatic( parent, context ) )
2165 if ( !mHigherBound->isStatic( parent, context ) )
2173 return mLowerBound.get();
2178 return mHigherBound.get();
2187 : mWhenExp( whenExp )
2188 , mThenExp( thenExp )
2200 return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
2205 return BINARY_OPERATOR_TEXT[mOp];
2212 const QVariant container = mContainer->eval( parent, context );
2214 const QVariant index = mIndex->eval( parent, context );
2217 switch ( container.userType() )
2219 case QMetaType::Type::QVariantMap:
2220 return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
2222 case QMetaType::Type::QVariantList:
2223 case QMetaType::Type::QStringList:
2225 const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
2226 qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
2227 if ( pos >= list.length() || pos < -list.length() )
2234 pos += list.length();
2237 return list.at( pos );
2242 parent->
setEvalErrorString( tr(
"[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName(
static_cast<QMetaType::Type
>( container.userType() ) ) ) );
2254 bool resC = mContainer->prepare( parent, context );
2255 bool resV = mIndex->prepare( parent, context );
2256 return resC && resV;
2261 return QStringLiteral(
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
2267 return QSet< QString >();
2269 return mContainer->referencedColumns() + mIndex->referencedColumns();
2274 return mContainer->referencedVariables() + mIndex->referencedVariables();
2279 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
2284 QList<const QgsExpressionNode *> lst;
2286 lst += mContainer->nodes() + mIndex->nodes();
2292 return mContainer->needsGeometry() || mIndex->needsGeometry();
2304 return mContainer->
isStatic( parent, context ) && mIndex->isStatic( parent, context );
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
bool hasFeature() const
Returns true if the context has a feature associated with it.
Represents a single parameter passed to a function.
QVariant defaultValue() const
Returns the default value for the parameter.
QString name() const
Returns the name of the parameter.
An abstract base class for defining QgsExpression functions.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
int params() const
The number of parameters this function takes.
bool lazyEval() const
true if this function should use lazy evaluation.
QString name() const
The name of the function.
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
virtual bool prepare(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.
SQL-like BETWEEN and NOT BETWEEN predicates.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
bool negate() const
Returns true if the predicate is an exclusion test (NOT BETWEEN).
QgsExpressionNode * lowerBound() const
Returns the lower bound expression node of the range.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QgsExpressionNode * higherBound() const
Returns the higher bound expression node of the range.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
~QgsExpressionNodeBetweenOperator() override
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
A binary expression operator, which operates on two values.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
bool leftAssociative() const
Returns true if the operator is left-associative.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
int precedence() const
Returns the precedence index for the operator.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString text() const
Returns a the name of this operator without the operands.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
BinaryOperator
list of binary operators
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
An expression node which takes its value from a feature's field.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Represents a "WHEN... THEN..." portation of a CASE WHEN clause in an expression.
WhenThen(QgsExpressionNode *whenExp, QgsExpressionNode *thenExp)
A combination of when and then.
QgsExpressionNodeCondition::WhenThen * clone() const
Gets a deep copy of this WhenThen combination.
An expression node for CASE WHEN clauses.
QList< QgsExpressionNodeCondition::WhenThen * > WhenThenList
QgsExpressionNodeCondition(QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp=nullptr)
Create a new node with the given list of conditions and an optional elseExp expression.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
QgsExpressionNode * clone() const override
Generate a clone of this node.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
WhenThenList conditions() const
The list of WHEN THEN expression parts of the expression.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
~QgsExpressionNodeCondition() override
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
An expression node for expression functions.
int fnIndex() const
Returns the index of the node's function.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
~QgsExpressionNodeFunction() override
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QgsExpressionNodeFunction(int fnIndex, QgsExpressionNode::NodeList *args)
A function node consists of an index of the function in the global function array and a list of argum...
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
static bool validateParams(int fnIndex, QgsExpressionNode::NodeList *args, QString &error)
Tests whether the provided argument list is valid for the matching function.
An expression node for value IN or NOT IN clauses.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
~QgsExpressionNodeInOperator() override
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QgsExpressionNode::NodeList * list() const
Returns the list of nodes to search for matching values within.
An indexing expression operator, which allows use of square brackets [] to reference map and array it...
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
An expression node for literal values.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QString valueAsString() const
Returns a string representation of the node's literal value.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QgsExpressionNode * clone() const override
Generate a clone of this node.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QVariant value() const
The value of the literal.
A unary node is either negative as in boolean (not) or as in numbers (minus).
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QString text() const
Returns a the name of this operator without the operands.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
A list of expression nodes.
bool hasNamedNodes() const
Returns true if list contains any named nodes.
virtual QString dump() const
Returns a string dump of the expression node.
QStringList names() const
Returns a list of names for nodes.
QgsExpressionNode::NodeList * clone() const
Creates a deep copy of this list. Ownership is transferred to the caller.
void append(QgsExpressionNode *node)
Takes ownership of the provided node.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
Abstract base class for all nodes that can appear in an expression.
bool hasCachedStaticValue() const
Returns true if the node can be replaced by a static cached value.
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
bool mHasCachedValue
true if the node has a static, precalculated value.
QVariant mCachedStaticValue
Contains the static, precalculated value for the node if mHasCachedValue is true.
std::unique_ptr< QgsExpressionNode > mCompiledSimplifiedNode
Contains a compiled node which represents a simplified version of this node as a result of compilatio...
NodeType
Known node types.
@ ntBetweenOperator
Between operator.
@ ntIndexOperator
Index operator.
virtual QList< const QgsExpressionNode * > nodes() const =0
Returns a list of all nodes which are used in this expression.
void cloneTo(QgsExpressionNode *target) const
Copies the members of this node to the node provided in target.
Handles parsing and evaluation of expressions (formerly called "search strings").
static const QList< QgsExpressionFunction * > & Functions()
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Container of fields for a vector layer.
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A representation of the interval between two datetime values.
double seconds() const
Returns the interval duration in seconds.
static QString qRegExpEscape(const QString &string)
Returns an escaped string matching the behavior of QRegExp::escape.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
bool compareOp(T diff, QgsExpressionNodeBinaryOperator::BinaryOperator op)
#define ENSURE_NO_EVAL_ERROR
#define SET_EVAL_ERROR(x)
QgsExpressionNode * node
Node.