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];
207 QVariant vL = mOpLeft->eval( parent, context );
210 if ( mOp == boAnd || mOp == boOr )
212 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
214 if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
216 if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
220 QVariant vR = mOpRight->eval( parent, context );
226 if ( vL.userType() == QMetaType::Type::QString && vR.userType() == QMetaType::Type::QString )
228 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
230 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
232 return QVariant( sL + sR );
241 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
243 else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
246 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
248 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
251 if ( mOp == boMod && iR == 0 )
254 return QVariant( computeInt( iL, iR ) );
256 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
258 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
260 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
262 if ( mOp == boDiv || mOp == boMul || mOp == boMod )
264 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
267 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
269 else if ( mOp == boPlus && ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QTime ) ||
270 ( vR.userType() == QMetaType::Type::QDate && vL.userType() == QMetaType::Type::QTime ) ) )
272 QDate date = QgsExpressionUtils::getDateValue( vL.userType() == QMetaType::Type::QDate ? vL : vR, parent );
274 QTime time = QgsExpressionUtils::getTimeValue( vR.userType() == QMetaType::Type::QTime ? vR : vL, parent );
276 QDateTime dt = QDateTime( date, time );
277 return QVariant( dt );
279 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate )
281 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
283 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
285 return date1 - date2;
287 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime )
289 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
291 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
293 return time1 - time2;
295 else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime )
297 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
299 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
306 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
308 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
310 if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
312 return QVariant( computeDouble( fL, fR ) );
318 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
320 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
324 return QVariant( qlonglong( std::floor( fL / fR ) ) );
327 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
331 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
333 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
335 return QVariant( std::pow( fL, fR ) );
340 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
342 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
347 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
349 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
358 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
362 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
365 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
369 QVariantList lL = vL.toList();
370 QVariantList lR = vR.toList();
371 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
373 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
376 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
386 return QgsExpressionUtils::isNull( lR.at( i ) );
389 return QgsExpressionUtils::isNull( lL.at( i ) );
399 QVariant eq = eqNode.
eval( parent, context );
401 if ( eq == TVL_False )
405 QVariant v = node.
eval( parent, context );
415 return lL.length() == lR.length();
417 return lL.length() != lR.length();
419 return lL.length() < lR.length();
421 return lL.length() > lR.length();
423 return lL.length() <= lR.length();
425 return lL.length() >= lR.length();
431 else if ( ( vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime ) )
433 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
435 QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
442 dL.setTimeSpec( Qt::UTC );
443 dR.setTimeSpec( Qt::UTC );
445 return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
447 else if ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate ) )
449 const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
451 const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
453 return compare( dR.daysTo( dL ) ) ? TVL_True : TVL_False;
455 else if ( ( vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime ) )
457 const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
459 const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
461 return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
463 else if ( ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) &&
464 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
468 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
470 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
472 return compare( fL - fR ) ? TVL_True : TVL_False;
475 else if ( vL.userType() == QMetaType::Type::Bool || vR.userType() == QMetaType::Type::Bool )
481 if ( vL.userType() == QMetaType::Type::Bool && vR.userType() == QMetaType::Type::Bool )
482 return vL.toBool() == vR.toBool() ? TVL_True : TVL_False;
487 else if ( vL.userType() == qMetaTypeId< QgsInterval>() && vR.userType() == qMetaTypeId< QgsInterval>() )
489 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
491 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
493 return compare( fL - fR ) ? TVL_True : TVL_False;
498 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
500 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
502 int diff = QString::compare( sL, sR );
503 return compare( diff ) ? TVL_True : TVL_False;
508 if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) )
509 return ( mOp == boIs ? TVL_True : TVL_False );
510 else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
511 return ( mOp == boIs ? TVL_False : TVL_True );
515 if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
516 ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) )
518 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
520 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
526 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
528 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
530 equal = QString::compare( sL, sR ) == 0;
533 return mOp == boIs ? TVL_True : TVL_False;
535 return mOp == boIs ? TVL_False : TVL_True;
543 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
547 QString str = QgsExpressionUtils::getStringValue( vL, parent );
549 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
553 if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike )
557 if ( esc_regexp.startsWith(
'%' ) )
559 esc_regexp.replace( 0, 1, QStringLiteral(
".*" ) );
561 const thread_local QRegularExpression rx1( QStringLiteral(
"[^\\\\](%)" ) );
563 while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
565 esc_regexp.replace( pos + 1, 1, QStringLiteral(
".*" ) );
568 const thread_local QRegularExpression rx2( QStringLiteral(
"\\\\%" ) );
569 esc_regexp.replace( rx2, QStringLiteral(
"%" ) );
570 if ( esc_regexp.startsWith(
'_' ) )
572 esc_regexp.replace( 0, 1, QStringLiteral(
"." ) );
574 const thread_local QRegularExpression rx3( QStringLiteral(
"[^\\\\](_)" ) );
576 while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
578 esc_regexp.replace( pos + 1, 1,
'.' );
581 esc_regexp.replace( QLatin1String(
"\\\\_" ), QLatin1String(
"_" ) );
583 matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp == boLike || mOp == boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption ).match( str ).hasMatch();
587 matches = QRegularExpression( regexp ).match( str ).hasMatch();
590 if ( mOp == boNotLike || mOp == boNotILike )
595 return matches ? TVL_True : TVL_False;
599 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
603 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
605 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
607 return QVariant( sL + sR );
614bool QgsExpressionNodeBinaryOperator::compare(
double diff )
636qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
656QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d,
QgsInterval *i )
661 return d.addSecs( i->
seconds() );
663 return d.addSecs( -i->
seconds() );
670double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
683 return std::fmod( x, y );
703 QMap<QString, QgsExpressionNode::NodeList> orValuesMap;
704 QList<QString> orFieldNames;
711 if ( op->op() != boOr && op->op() != boEQ )
716 if ( op->op() == boEQ )
721 const QString fieldName = op->opLeft()->dump();
722 if ( !orValuesMap.contains( fieldName ) )
724 orFieldNames.append( fieldName );
727 orValuesMap[fieldName].append( op->opRight()->clone() );
732 const QString fieldName = op->opRight()->dump();
733 if ( !orValuesMap.contains( fieldName ) )
735 orFieldNames.append( fieldName );
738 orValuesMap[fieldName].append( op->opLeft()->clone() );
744 if ( visitOrNodes( op->opLeft() ) && visitOrNodes( op->opRight() ) )
757 const QString fieldName = inOp->node()->dump();
760 const auto nodes = inOp->list()->list();
761 for (
const auto &valueNode : std::as_const(
nodes ) )
769 if ( !orValuesMap.contains( fieldName ) )
771 orFieldNames.append( fieldName );
772 orValuesMap.insert( fieldName, *inOp->list()->clone() );
776 for (
const auto &valueNode : std::as_const(
nodes ) )
778 orValuesMap[fieldName].append( valueNode->clone() );
789 if ( visitOrNodes(
this ) && ! orValuesMap.empty() )
792 std::unique_ptr<QgsExpressionNode> currentNode;
793 for (
const auto &fieldName : std::as_const( orFieldNames ) )
795 auto orValuesIt = orValuesMap.find( fieldName );
796 if ( orValuesIt.value().count() == 1 )
798 auto eqNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boEQ,
new QgsExpressionNodeColumnRef( fieldName ), orValuesIt.value().at( 0 )->
clone() );
801 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), eqNode.release() );
805 currentNode = std::move( eqNode );
813 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), inNode.release() );
817 currentNode = std::move( inNode );
831 bool resL = mOpLeft->prepare( parent, context );
832 bool resR = mOpRight->prepare( parent, context );
878 Q_ASSERT(
false &&
"unexpected binary operator" );
914 Q_ASSERT(
false &&
"unexpected binary operator" );
924 QString rdump( mOpRight->dump() );
929 rdump.prepend(
'(' ).append(
')' );
933 if ( leftAssociative() )
935 fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
936 fmt += QLatin1String(
" %2 " );
937 fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
941 fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
942 fmt += QLatin1String(
" %2 " );
943 fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
946 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
952 return QSet< QString >();
954 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
959 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
964 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
969 QList<const QgsExpressionNode *> lst;
971 lst += mOpLeft->nodes() + mOpRight->nodes();
977 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
989 const bool leftStatic = mOpLeft->
isStatic( parent, context );
990 const bool rightStatic = mOpRight->isStatic( parent, context );
992 if ( leftStatic && rightStatic )
1004 mOpLeft->prepare( parent, context );
1005 if ( mOpLeft->hasCachedStaticValue() )
1007 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1008 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1016 else if ( rightStatic )
1018 mOpRight->prepare( parent, context );
1019 if ( mOpRight->hasCachedStaticValue() )
1021 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1022 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1040 mOpLeft->prepare( parent, context );
1041 if ( mOpLeft->hasCachedStaticValue() )
1043 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1044 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1052 else if ( rightStatic )
1054 mOpRight->prepare( parent, context );
1055 if ( mOpRight->hasCachedStaticValue() )
1057 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1058 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1101 if ( mList->count() == 0 )
1102 return mNotIn ? TVL_True : TVL_False;
1103 QVariant v1 = mNode->eval( parent, context );
1105 if ( QgsExpressionUtils::isNull( v1 ) )
1108 bool listHasNull =
false;
1110 const QList< QgsExpressionNode * > nodeList = mList->list();
1113 QVariant v2 = n->eval( parent, context );
1115 if ( QgsExpressionUtils::isNull( v2 ) )
1121 if ( ( v1.userType() != QMetaType::Type::QString || v2.userType() != QMetaType::Type::QString ) &&
1122 QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
1126 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
1128 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
1134 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
1136 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
1138 equal = QString::compare( s1, s2 ) == 0;
1142 return mNotIn ? TVL_False : TVL_True;
1150 return mNotIn ? TVL_True : TVL_False;
1164 bool res = mNode->prepare( parent, context );
1165 const QList< QgsExpressionNode * > nodeList = mList->list();
1168 res = res && n->prepare( parent, context );
1175 return QStringLiteral(
"%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ?
"NOT" :
"", mList->dump() );
1187 if ( !mNode->isStatic( parent, context ) )
1190 const QList< QgsExpressionNode * > nodeList = mList->
list();
1193 if ( !n->isStatic( parent, context ) )
1204 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
1207 QVariant res = fd->
run( mArgs.get(), context, parent,
this );
1215 : mFnIndex( fnIndex )
1220 QMutexLocker locker( &QgsExpression::QgsExpression::sFunctionsMutex );
1223 const int functionParamsSize = functionParams.size();
1224 if ( functionParams.isEmpty() )
1227 mArgs.reset(
args );
1232 mArgs = std::make_unique<NodeList>();
1233 mArgs->reserve( functionParamsSize );
1242 mArgs = std::make_unique<NodeList>();
1243 mArgs->reserve( functionParamsSize );
1246 const QStringList argNames =
args->
names();
1247 const QList<QgsExpressionNode *> argList =
args->
list();
1250 const int argNamesSize = argNames.size();
1251 while ( idx < argNamesSize && argNames.at( idx ).isEmpty() )
1253 mArgs->append( argList.at( idx )->clone() );
1259 for ( ; idx < functionParamsSize; ++idx )
1262 int nodeIdx = argNames.indexOf( parameter.
name().toLower() );
1270 mArgs->append( argList.at( nodeIdx )->clone() );
1292 bool res = fd->
prepare(
this, parent, context );
1295 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1298 res = res && n->prepare( parent, context );
1308 return QStringLiteral(
"%1%2" ).arg( fd->
name(), fd->
name().startsWith(
'$' ) ? QString() : QStringLiteral(
"()" ) );
1310 return QStringLiteral(
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->dump() : QString() );
1316 return QSet< QString >();
1324 return functionColumns;
1328 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1331 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
1332 functionColumns.unite( n->referencedColumns() );
1336 return functionColumns;
1342 if ( fd->
name() == QLatin1String(
"var" ) )
1344 if ( !mArgs->list().isEmpty() )
1348 return QSet<QString>() << var->
value().toString();
1350 return QSet<QString>() << QString();
1354 QSet<QString> functionVariables = QSet<QString>();
1357 return functionVariables;
1359 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1362 functionVariables.unite( n->referencedVariables() );
1365 return functionVariables;
1372 QSet<QString> functions = QSet<QString>();
1373 functions.insert( fd->
name() );
1378 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1381 functions.unite( n->referencedFunctions() );
1388 QList<const QgsExpressionNode *> lst;
1393 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1403 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1406 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1408 needs |= n->needsGeometry();
1431 if ( functionParams.isEmpty() )
1438 QSet< int > providedArgs;
1439 QSet< int > handledArgs;
1442 while (
args->
names().at( idx ).isEmpty() )
1444 providedArgs << idx;
1450 for ( ; idx < functionParams.count(); ++idx )
1452 int nodeIdx =
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
1455 if ( !functionParams.at( idx ).optional() )
1457 error = QStringLiteral(
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1463 if ( providedArgs.contains( idx ) )
1465 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1469 providedArgs << idx;
1470 handledArgs << nodeIdx;
1475 const QStringList nameList =
args->
names();
1476 for (
const QString &name : nameList )
1478 if ( !name.isEmpty() && !functionParams.contains( name ) )
1483 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1485 int functionIdx = functionParams.indexOf( name );
1486 if ( providedArgs.contains( functionIdx ) )
1488 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1524 return QStringLiteral(
"NULL" );
1526 switch ( mValue.userType() )
1528 case QMetaType::Type::Int:
1529 return QString::number( mValue.toInt() );
1530 case QMetaType::Type::Double:
1532 case QMetaType::Type::LongLong:
1533 return QString::number( mValue.toLongLong() );
1534 case QMetaType::Type::QString:
1536 case QMetaType::Type::QTime:
1538 case QMetaType::Type::QDate:
1540 case QMetaType::Type::QDateTime:
1542 case QMetaType::Type::Bool:
1543 return mValue.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
1545 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1556 return QSet<QString>();
1561 return QSet<QString>();
1566 return QSet<QString>();
1571 QList<const QgsExpressionNode *> lst;
1624 parent->
setEvalErrorString( tr(
"No feature available for field '%1' evaluation" ).arg( mName ) );
1661 const thread_local QRegularExpression re( QStringLiteral(
"^[A-Za-z_\\x80-\\xff][A-Za-z0-9_\\x80-\\xff]*$" ) );
1662 const QRegularExpressionMatch match = re.match( mName );
1668 return QSet<QString>() << mName;
1673 return QSet<QString>();
1678 return QSet<QString>();
1683 QList<const QgsExpressionNode *> result;
1710 : mConditions( *conditions )
1711 , mElseExp( elseExp )
1719 qDeleteAll( mConditions );
1729 for (
WhenThen *cond : std::as_const( mConditions ) )
1731 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1732 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1734 if ( tvl == QgsExpressionUtils::True )
1736 QVariant vRes = cond->mThenExp->eval( parent, context );
1744 QVariant vElse = mElseExp->eval( parent, context );
1755 bool foundAnyNonStaticConditions =
false;
1756 for (
WhenThen *cond : std::as_const( mConditions ) )
1758 const bool res = cond->mWhenExp->prepare( parent, context )
1759 && cond->mThenExp->prepare( parent, context );
1763 foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
1764 if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
1768 if ( cond->mThenExp->hasCachedStaticValue() )
1787 const bool res = mElseExp->prepare( parent, context );
1791 if ( !foundAnyNonStaticConditions )
1794 if ( mElseExp->hasCachedStaticValue() )
1815 QString msg( QStringLiteral(
"CASE" ) );
1816 for (
WhenThen *cond : mConditions )
1818 msg += QStringLiteral(
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1821 msg += QStringLiteral(
" ELSE %1" ).arg( mElseExp->dump() );
1822 msg += QLatin1String(
" END" );
1829 return QSet< QString >();
1832 for (
WhenThen *cond : mConditions )
1834 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1838 lst += mElseExp->referencedColumns();
1846 for (
WhenThen *cond : mConditions )
1848 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1852 lst += mElseExp->referencedVariables();
1860 for (
WhenThen *cond : mConditions )
1862 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1866 lst += mElseExp->referencedFunctions();
1873 QList<const QgsExpressionNode *> lst;
1875 for (
WhenThen *cond : mConditions )
1877 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1881 lst += mElseExp->nodes();
1888 for (
WhenThen *cond : mConditions )
1890 if ( cond->mWhenExp->needsGeometry() ||
1891 cond->mThenExp->needsGeometry() )
1895 return mElseExp && mElseExp->needsGeometry();
1914 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1919 return mElseExp->isStatic( parent, context );
1927 return QSet< QString >();
1929 QSet<QString> lst( mNode->referencedColumns() );
1930 const QList< QgsExpressionNode * > nodeList = mList->list();
1932 lst.unite( n->referencedColumns() );
1938 QSet<QString> lst( mNode->referencedVariables() );
1939 const QList< QgsExpressionNode * > nodeList = mList->list();
1941 lst.unite( n->referencedVariables() );
1947 QSet<QString> lst( mNode->referencedFunctions() );
1948 const QList< QgsExpressionNode * > nodeList = mList->list();
1950 lst.unite( n->referencedFunctions() );
1956 QList<const QgsExpressionNode *> lst;
1958 const QList< QgsExpressionNode * > nodeList = mList->list();
1976 bool res = mNode->prepare( parent, context );
1977 res = res && mLowerBound->prepare( parent, context );
1978 res = res && mHigherBound->prepare( parent, context );
1984 const QVariant nodeVal = mNode->eval( parent, context );
1993 const QVariant lowBoundValue = lowBound.eval( parent, context );
1994 const bool lowBoundBool { lowBoundValue.toBool() };
1998 return QVariant( mNegate );
2002 const QVariant highBoundValue = highBound.eval( parent, context );
2009 const bool highBoundBool { highBoundValue.toBool() };
2019 return QVariant( mNegate );
2029 return QVariant( mNegate );
2032 const bool res { lowBoundBool &&highBoundBool };
2033 return mNegate ? QVariant( ! res ) : QVariant( res );
2039 return QStringLiteral(
"%1 %2 %3 AND %4" ).arg( mNode->dump(), mNegate ? QStringLiteral(
"NOT BETWEEN" ) : QStringLiteral(
"BETWEEN" ), mLowerBound->dump(), mHigherBound->dump() );
2044 QSet<QString> lst( mNode->referencedVariables() );
2045 lst.unite( mLowerBound->referencedVariables() );
2046 lst.unite( mHigherBound->referencedVariables() );
2052 QSet<QString> lst( mNode->referencedFunctions() );
2053 lst.unite( mLowerBound->referencedFunctions() );
2054 lst.unite( mHigherBound->referencedFunctions() );
2060 return {
this, mLowerBound.get(), mHigherBound.get() };
2065 QSet<QString> lst( mNode->referencedColumns() );
2066 lst.unite( mLowerBound->referencedColumns() );
2067 lst.unite( mHigherBound->referencedColumns() );
2073 if ( mNode->needsGeometry() )
2076 if ( mLowerBound->needsGeometry() )
2079 if ( mHigherBound->needsGeometry() )
2094 if ( !mNode->isStatic( parent, context ) )
2097 if ( !mLowerBound->isStatic( parent, context ) )
2100 if ( !mHigherBound->isStatic( parent, context ) )
2108 return mLowerBound.get();
2113 return mHigherBound.get();
2122 : mWhenExp( whenExp )
2123 , mThenExp( thenExp )
2135 return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
2140 return BINARY_OPERATOR_TEXT[mOp];
2147 const QVariant container = mContainer->eval( parent, context );
2149 const QVariant index = mIndex->eval( parent, context );
2152 switch ( container.userType() )
2154 case QMetaType::Type::QVariantMap:
2155 return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
2157 case QMetaType::Type::QVariantList:
2158 case QMetaType::Type::QStringList:
2160 const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
2161 qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
2162 if ( pos >= list.length() || pos < -list.length() )
2169 pos += list.length();
2172 return list.at( pos );
2177 parent->
setEvalErrorString( tr(
"[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName(
static_cast<QMetaType::Type
>( container.userType() ) ) ) );
2189 bool resC = mContainer->prepare( parent, context );
2190 bool resV = mIndex->prepare( parent, context );
2191 return resC && resV;
2196 return QStringLiteral(
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
2202 return QSet< QString >();
2204 return mContainer->referencedColumns() + mIndex->referencedColumns();
2209 return mContainer->referencedVariables() + mIndex->referencedVariables();
2214 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
2219 QList<const QgsExpressionNode *> lst;
2221 lst += mContainer->nodes() + mIndex->nodes();
2227 return mContainer->needsGeometry() || mIndex->needsGeometry();
2239 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.
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)
#define ENSURE_NO_EVAL_ERROR
#define SET_EVAL_ERROR(x)
QgsExpressionNode * node
Node.