25#include <QRegularExpression>
29using namespace Qt::StringLiterals;
31const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
35 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
36 "+",
"-",
"*",
"/",
"//",
"%",
"^",
40const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
49 const QList< QgsExpressionNode * > nodeList = mList->list();
51 needs |= n->needsGeometry();
62 mList.append( node->
node );
63 mNameList.append( cleanNamedNodeName( node->
name ) );
64 mHasNamedNodes =
true;
73 nl->mList.append( node->clone() );
75 nl->mNameList = mNameList;
86 if ( !first ) msg +=
", "_L1;
93QString QgsExpressionNode::NodeList::cleanNamedNodeName(
const QString &name )
95 QString cleaned = name.toLower();
98 if ( cleaned ==
"geom"_L1 )
99 cleaned = u
"geometry"_s;
100 else if ( cleaned ==
"val"_L1 )
101 cleaned = u
"value"_s;
102 else if ( cleaned ==
"geometry a"_L1 )
103 cleaned = u
"geometry1"_s;
104 else if ( cleaned ==
"geometry b"_L1 )
105 cleaned = u
"geometry2"_s;
106 else if ( cleaned ==
"i"_L1 )
107 cleaned = u
"vertex"_s;
117 QVariant val = mOperand->eval( parent, context );
124 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
126 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
130 if ( QgsExpressionUtils::isIntSafe( val ) )
131 return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
132 else if ( QgsExpressionUtils::isDoubleSafe( val ) )
133 return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
147 return mOperand->prepare( parent, context );
153 return u
"%1 ( %2 )"_s.arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
155 return u
"%1 %2"_s.arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
161 return QSet< QString >();
163 return mOperand->referencedColumns();
168 return mOperand->referencedVariables();
173 return mOperand->referencedFunctions();
178 QList<const QgsExpressionNode *> lst;
180 lst += mOperand->nodes();
186 return mOperand->needsGeometry();
198 return mOperand->
isStatic( parent, context );
203 return UNARY_OPERATOR_TEXT[mOp];
254QVariant QgsExpressionNodeBinaryOperator::compareNonNullValues( QgsExpression *parent,
const QgsExpressionContext *,
const QVariant &vL,
const QVariant &vR, BinaryOperator op )
256 if ( ( vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime ) )
258 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
260 QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
267 dL.setTimeSpec( Qt::UTC );
268 dR.setTimeSpec( Qt::UTC );
272 else if ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate ) )
274 const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
276 const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
280 else if ( ( vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime ) )
282 const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
284 const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
286 return compareOp<int>( dR.msecsTo( dL ), op ) ? TVL_True : TVL_False;
288 else if ( ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) &&
289 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
293 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
295 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
300 else if ( vL.userType() == QMetaType::Type::Bool || vR.userType() == QMetaType::Type::Bool )
322 const bool vLBool = vL.toBool();
323 const bool vRBool = vR.toBool();
327 return vLBool == vRBool ? TVL_True : TVL_False;
329 return vLBool != vRBool ? TVL_True : TVL_False;
331 return vLBool < vRBool ? TVL_True : TVL_False;
333 return vLBool <= vRBool ? TVL_True : TVL_False;
335 return vLBool > vRBool ? TVL_True : TVL_False;
337 return vLBool >= vRBool ? TVL_True : TVL_False;
362 else if ( vL.userType() == qMetaTypeId< QgsInterval>() && vR.userType() == qMetaTypeId< QgsInterval>() )
364 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
366 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
373 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
375 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
377 int diff = QString::compare( sL, sR );
384 QVariant vL = mOpLeft->eval( parent, context );
389 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
391 if ( mOp ==
boAnd && tvlL == QgsExpressionUtils::False )
393 if ( mOp ==
boOr && tvlL == QgsExpressionUtils::True )
397 QVariant vR = mOpRight->eval( parent, context );
403 if ( vL.userType() == QMetaType::Type::QString && vR.userType() == QMetaType::Type::QString )
405 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
407 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
409 return QVariant( sL + sR );
418 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
420 else if ( mOp !=
boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
423 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
425 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
428 if ( mOp ==
boMod && iR == 0 )
431 return QVariant( computeInt( iL, iR ) );
433 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
435 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
437 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
441 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
444 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
446 else if ( mOp ==
boPlus && ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QTime ) ||
447 ( vR.userType() == QMetaType::Type::QDate && vL.userType() == QMetaType::Type::QTime ) ) )
449 QDate date = QgsExpressionUtils::getDateValue( vL.userType() == QMetaType::Type::QDate ? vL : vR, parent );
451 QTime time = QgsExpressionUtils::getTimeValue( vR.userType() == QMetaType::Type::QTime ? vR : vL, parent );
453 QDateTime dt = QDateTime( date, time );
454 return QVariant( dt );
456 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate )
458 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
460 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
462 return date1 - date2;
464 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime )
466 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
468 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
470 return time1 - time2;
472 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime )
474 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
476 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
483 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
485 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
487 if ( ( mOp ==
boDiv || mOp ==
boMod ) && fR == 0. )
489 return QVariant( computeDouble( fL, fR ) );
495 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
497 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
501 return QVariant( qlonglong( std::floor( fL / fR ) ) );
504 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
508 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
510 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
512 return QVariant( std::pow( fL, fR ) );
517 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
519 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
524 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
526 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
535 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
539 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
542 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
546 QVariantList lL = vL.toList();
547 QVariantList lR = vR.toList();
548 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
550 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
553 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
563 return QgsExpressionUtils::isNull( lR.at( i ) );
566 return QgsExpressionUtils::isNull( lL.at( i ) );
576 QVariant eq = eqNode.
eval( parent, context );
578 if ( eq == TVL_False )
582 QVariant v = node.
eval( parent, context );
592 return lL.length() == lR.length();
594 return lL.length() != lR.length();
596 return lL.length() < lR.length();
598 return lL.length() > lR.length();
600 return lL.length() <= lR.length();
602 return lL.length() >= lR.length();
610 return compareNonNullValues( parent, context, vL, vR, mOp );
616 const bool vLNull = QgsExpressionUtils::isNull( vL );
617 const bool vRNull = QgsExpressionUtils::isNull( vR );
618 if ( vLNull && vRNull )
619 return ( mOp ==
boIs ? TVL_True : TVL_False );
620 else if ( vLNull || vRNull )
621 return ( mOp ==
boIs ? TVL_False : TVL_True );
624 return compareNonNullValues( parent, context, vL, vR, mOp ==
boIs ?
boEQ :
boNE );
633 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
637 QString str = QgsExpressionUtils::getStringValue( vL, parent );
639 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
647 if ( esc_regexp.startsWith(
'%' ) )
649 esc_regexp.replace( 0, 1, u
".*"_s );
651 const thread_local QRegularExpression rx1( u
"[^\\\\](%)"_s );
653 while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
655 esc_regexp.replace( pos + 1, 1, u
".*"_s );
658 const thread_local QRegularExpression rx2( u
"\\\\%"_s );
659 esc_regexp.replace( rx2, u
"%"_s );
660 if ( esc_regexp.startsWith(
'_' ) )
662 esc_regexp.replace( 0, 1, u
"."_s );
664 const thread_local QRegularExpression rx3( u
"[^\\\\](_)"_s );
666 while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
668 esc_regexp.replace( pos + 1, 1,
'.' );
671 esc_regexp.replace(
"\\\\_"_L1,
"_"_L1 );
673 matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp ==
boLike || mOp ==
boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption ).match( str ).hasMatch();
677 matches = QRegularExpression( regexp ).match( str ).hasMatch();
685 return matches ? TVL_True : TVL_False;
689 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
693 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
695 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
697 return QVariant( sL + sR );
704qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
724QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d, QgsInterval *i )
729 return d.addSecs( i->
seconds() );
731 return d.addSecs( -i->
seconds() );
738double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
751 return std::fmod( x, y );
771 QMap<QString, QgsExpressionNode::NodeList> orValuesMap;
772 QList<QString> orFieldNames;
789 const QString fieldName =
op->opLeft()->dump();
790 if ( !orValuesMap.contains( fieldName ) )
792 orFieldNames.append( fieldName );
795 orValuesMap[fieldName].append(
op->opRight()->clone() );
800 const QString fieldName =
op->opRight()->dump();
801 if ( !orValuesMap.contains( fieldName ) )
803 orFieldNames.append( fieldName );
806 orValuesMap[fieldName].append(
op->opLeft()->clone() );
812 if ( visitOrNodes(
op->opLeft() ) && visitOrNodes(
op->opRight() ) )
825 const QString fieldName = inOp->node()->dump();
828 const auto nodes = inOp->list()->list();
829 for (
const auto &valueNode : std::as_const(
nodes ) )
837 if ( !orValuesMap.contains( fieldName ) )
839 orFieldNames.append( fieldName );
840 orValuesMap.insert( fieldName, *inOp->list()->clone() );
844 for (
const auto &valueNode : std::as_const(
nodes ) )
846 orValuesMap[fieldName].append( valueNode->clone() );
857 if ( visitOrNodes(
this ) && ! orValuesMap.empty() )
860 std::unique_ptr<QgsExpressionNode> currentNode;
861 for (
const auto &fieldName : std::as_const( orFieldNames ) )
863 auto orValuesIt = orValuesMap.find( fieldName );
864 if ( orValuesIt.value().count() == 1 )
869 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>(
boOr, currentNode.release(), eqNode.release() );
873 currentNode = std::move( eqNode );
881 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>(
boOr, currentNode.release(), inNode.release() );
885 currentNode = std::move( inNode );
899 bool resL = mOpLeft->prepare( parent, context );
900 bool resR = mOpRight->prepare( parent, context );
946 Q_ASSERT(
false &&
"unexpected binary operator" );
982 Q_ASSERT(
false &&
"unexpected binary operator" );
992 QString rdump( mOpRight->dump() );
997 rdump.prepend(
'(' ).append(
')' );
1014 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
1020 return QSet< QString >();
1022 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
1027 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
1032 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
1037 QList<const QgsExpressionNode *> lst;
1039 lst += mOpLeft->nodes() + mOpRight->nodes();
1045 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
1057 const bool leftStatic = mOpLeft->
isStatic( parent, context );
1058 const bool rightStatic = mOpRight->isStatic( parent, context );
1060 if ( leftStatic && rightStatic )
1072 mOpLeft->prepare( parent, context );
1073 if ( mOpLeft->hasCachedStaticValue() )
1075 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1076 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1084 else if ( rightStatic )
1086 mOpRight->prepare( parent, context );
1087 if ( mOpRight->hasCachedStaticValue() )
1089 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1090 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1108 mOpLeft->prepare( parent, context );
1109 if ( mOpLeft->hasCachedStaticValue() )
1111 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1112 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1120 else if ( rightStatic )
1122 mOpRight->prepare( parent, context );
1123 if ( mOpRight->hasCachedStaticValue() )
1125 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1126 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1169 if ( mList->count() == 0 )
1170 return mNotIn ? TVL_True : TVL_False;
1171 QVariant v1 = mNode->eval( parent, context );
1173 if ( QgsExpressionUtils::isNull( v1 ) )
1176 bool listHasNull =
false;
1178 const QList< QgsExpressionNode * > nodeList = mList->list();
1181 QVariant v2 = n->eval( parent, context );
1183 if ( QgsExpressionUtils::isNull( v2 ) )
1189 if ( ( v1.userType() != QMetaType::Type::QString || v2.userType() != QMetaType::Type::QString ) &&
1190 QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
1194 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
1196 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
1202 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
1204 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
1206 equal = QString::compare( s1, s2 ) == 0;
1210 return mNotIn ? TVL_False : TVL_True;
1218 return mNotIn ? TVL_True : TVL_False;
1232 bool res = mNode->prepare( parent, context );
1233 const QList< QgsExpressionNode * > nodeList = mList->list();
1236 res = res && n->prepare( parent, context );
1243 return u
"%1 %2 IN (%3)"_s.arg( mNode->dump(), mNotIn ?
"NOT" :
"", mList->dump() );
1255 if ( !mNode->isStatic( parent, context ) )
1258 const QList< QgsExpressionNode * > nodeList = mList->
list();
1261 if ( !n->isStatic( parent, context ) )
1272 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
1275 QVariant res = fd->
run( mArgs.get(), context, parent,
this );
1288 QMutexLocker locker( &QgsExpression::QgsExpression::sFunctionsMutex );
1291 const int functionParamsSize = functionParams.size();
1292 if ( functionParams.isEmpty() )
1295 mArgs.reset(
args );
1300 mArgs = std::make_unique<NodeList>();
1301 mArgs->reserve( functionParamsSize );
1310 mArgs = std::make_unique<NodeList>();
1311 mArgs->reserve( functionParamsSize );
1314 const QStringList argNames =
args->names();
1315 const QList<QgsExpressionNode *> argList =
args->list();
1318 const int argNamesSize = argNames.size();
1319 while ( idx < argNamesSize && argNames.at( idx ).isEmpty() )
1321 mArgs->append( argList.at( idx )->clone() );
1327 for ( ; idx < functionParamsSize; ++idx )
1330 int nodeIdx = argNames.indexOf( parameter.
name().toLower() );
1338 mArgs->append( argList.at( nodeIdx )->clone() );
1360 bool res = fd->
prepare(
this, parent, context );
1363 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1366 res = res && n->prepare( parent, context );
1376 return u
"%1%2"_s.arg( fd->
name(), fd->
name().startsWith(
'$' ) ? QString() : u
"()"_s );
1378 return u
"%1(%2)"_s.arg( fd->
name(), mArgs ? mArgs->dump() : QString() );
1384 return QSet< QString >();
1392 return functionColumns;
1396 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1399 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
1400 functionColumns.unite( n->referencedColumns() );
1404 return functionColumns;
1410 if ( fd->
name() ==
"var"_L1 )
1412 if ( !mArgs->list().isEmpty() )
1416 return QSet<QString>() << var->
value().toString();
1418 return QSet<QString>() << QString();
1422 QSet<QString> functionVariables = QSet<QString>();
1425 return functionVariables;
1427 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1430 functionVariables.unite( n->referencedVariables() );
1433 return functionVariables;
1440 QSet<QString> functions = QSet<QString>();
1441 functions.insert( fd->
name() );
1446 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1449 functions.unite( n->referencedFunctions() );
1456 QList<const QgsExpressionNode *> lst;
1461 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1471 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1474 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1476 needs |= n->needsGeometry();
1495 if ( !
args || !
args->hasNamedNodes() )
1499 if ( functionParams.isEmpty() )
1506 QSet< int > providedArgs;
1507 QSet< int > handledArgs;
1510 while (
args->names().at( idx ).isEmpty() )
1512 providedArgs << idx;
1518 for ( ; idx < functionParams.count(); ++idx )
1520 int nodeIdx =
args->names().indexOf( functionParams.at( idx ).name().toLower() );
1523 if ( !functionParams.at( idx ).optional() )
1525 error = u
"No value specified for QgsExpressionFunction::Parameter '%1' for %2"_s.arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1531 if ( providedArgs.contains( idx ) )
1533 error = u
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2"_s.arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1537 providedArgs << idx;
1538 handledArgs << nodeIdx;
1543 const QStringList nameList =
args->names();
1544 for (
const QString &name : nameList )
1546 if ( !name.isEmpty() && !functionParams.contains( name ) )
1551 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1553 int functionIdx = functionParams.indexOf( name );
1554 if ( providedArgs.contains( functionIdx ) )
1556 error = u
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2"_s.arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1594 switch ( mValue.userType() )
1596 case QMetaType::Type::Int:
1597 return QString::number( mValue.toInt() );
1598 case QMetaType::Type::Double:
1600 case QMetaType::Type::LongLong:
1601 return QString::number( mValue.toLongLong() );
1602 case QMetaType::Type::QString:
1604 case QMetaType::Type::QTime:
1606 case QMetaType::Type::QDate:
1608 case QMetaType::Type::QDateTime:
1610 case QMetaType::Type::Bool:
1611 return mValue.toBool() ? u
"TRUE"_s : u
"FALSE"_s;
1613 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1624 return QSet<QString>();
1629 return QSet<QString>();
1634 return QSet<QString>();
1639 QList<const QgsExpressionNode *> lst;
1692 parent->
setEvalErrorString( tr(
"No feature available for field '%1' evaluation" ).arg( mName ) );
1729 const thread_local QRegularExpression re( u
"^[A-Za-z_\\x80-\\xff][A-Za-z0-9_\\x80-\\xff]*$"_s );
1730 const QRegularExpressionMatch match = re.match( mName );
1736 return QSet<QString>() << mName;
1741 return QSet<QString>();
1746 return QSet<QString>();
1751 QList<const QgsExpressionNode *> result;
1787 qDeleteAll( mConditions );
1797 for (
WhenThen *cond : std::as_const( mConditions ) )
1799 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1800 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1802 if ( tvl == QgsExpressionUtils::True )
1804 QVariant vRes = cond->mThenExp->eval( parent, context );
1812 QVariant vElse = mElseExp->eval( parent, context );
1823 bool foundAnyNonStaticConditions =
false;
1824 for (
WhenThen *cond : std::as_const( mConditions ) )
1826 const bool res = cond->mWhenExp->prepare( parent, context )
1827 && cond->mThenExp->prepare( parent, context );
1831 foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
1832 if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
1836 if ( cond->mThenExp->hasCachedStaticValue() )
1855 const bool res = mElseExp->prepare( parent, context );
1859 if ( !foundAnyNonStaticConditions )
1862 if ( mElseExp->hasCachedStaticValue() )
1883 QString msg( u
"CASE"_s );
1884 for (
WhenThen *cond : mConditions )
1886 msg += u
" WHEN %1 THEN %2"_s.arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1889 msg += u
" ELSE %1"_s.arg( mElseExp->dump() );
1897 return QSet< QString >();
1900 for (
WhenThen *cond : mConditions )
1902 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1906 lst += mElseExp->referencedColumns();
1914 for (
WhenThen *cond : mConditions )
1916 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1920 lst += mElseExp->referencedVariables();
1928 for (
WhenThen *cond : mConditions )
1930 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1934 lst += mElseExp->referencedFunctions();
1941 QList<const QgsExpressionNode *> lst;
1943 for (
WhenThen *cond : mConditions )
1945 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1949 lst += mElseExp->nodes();
1956 for (
WhenThen *cond : mConditions )
1958 if ( cond->mWhenExp->needsGeometry() ||
1959 cond->mThenExp->needsGeometry() )
1963 return mElseExp && mElseExp->needsGeometry();
1982 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1987 return mElseExp->
isStatic( parent, context );
1995 return QSet< QString >();
1997 QSet<QString> lst( mNode->referencedColumns() );
1998 const QList< QgsExpressionNode * > nodeList = mList->list();
2000 lst.unite( n->referencedColumns() );
2006 QSet<QString> lst( mNode->referencedVariables() );
2007 const QList< QgsExpressionNode * > nodeList = mList->list();
2009 lst.unite( n->referencedVariables() );
2015 QSet<QString> lst( mNode->referencedFunctions() );
2016 const QList< QgsExpressionNode * > nodeList = mList->list();
2018 lst.unite( n->referencedFunctions() );
2024 QList<const QgsExpressionNode *> lst;
2026 const QList< QgsExpressionNode * > nodeList = mList->list();
2044 bool res = mNode->prepare( parent, context );
2045 res = res && mLowerBound->prepare( parent, context );
2046 res = res && mHigherBound->prepare( parent, context );
2052 const QVariant nodeVal = mNode->eval( parent, context );
2061 const QVariant lowBoundValue = lowBound.
eval( parent, context );
2062 const bool lowBoundBool { lowBoundValue.toBool() };
2066 return QVariant( mNegate );
2070 const QVariant highBoundValue = highBound.
eval( parent, context );
2077 const bool highBoundBool { highBoundValue.toBool() };
2087 return QVariant( mNegate );
2097 return QVariant( mNegate );
2100 const bool res { lowBoundBool &&highBoundBool };
2101 return mNegate ? QVariant( ! res ) : QVariant( res );
2107 return u
"%1 %2 %3 AND %4"_s.arg( mNode->dump(), mNegate ? u
"NOT BETWEEN"_s : u
"BETWEEN"_s, mLowerBound->dump(), mHigherBound->dump() );
2112 QSet<QString> lst( mNode->referencedVariables() );
2113 lst.unite( mLowerBound->referencedVariables() );
2114 lst.unite( mHigherBound->referencedVariables() );
2120 QSet<QString> lst( mNode->referencedFunctions() );
2121 lst.unite( mLowerBound->referencedFunctions() );
2122 lst.unite( mHigherBound->referencedFunctions() );
2128 return {
this, mLowerBound.get(), mHigherBound.get() };
2133 QSet<QString> lst( mNode->referencedColumns() );
2134 lst.unite( mLowerBound->referencedColumns() );
2135 lst.unite( mHigherBound->referencedColumns() );
2141 if ( mNode->needsGeometry() )
2144 if ( mLowerBound->needsGeometry() )
2147 if ( mHigherBound->needsGeometry() )
2162 if ( !mNode->isStatic( parent, context ) )
2165 if ( !mLowerBound->isStatic( parent, context ) )
2168 if ( !mHigherBound->isStatic( parent, context ) )
2176 return mLowerBound.get();
2181 return mHigherBound.get();
2203 return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
2208 return BINARY_OPERATOR_TEXT[mOp];
2215 const QVariant
container = mContainer->eval( parent, context );
2217 const QVariant
index = mIndex->eval( parent, context );
2222 case QMetaType::Type::QVariantMap:
2223 return QgsExpressionUtils::getMapValue(
container, parent ).value(
index.toString() );
2225 case QMetaType::Type::QVariantList:
2226 case QMetaType::Type::QStringList:
2228 const QVariantList list = QgsExpressionUtils::getListValue(
container, parent );
2229 qlonglong pos = QgsExpressionUtils::getIntValue(
index, parent );
2230 if ( pos >= list.length() || pos < -list.length() )
2237 pos += list.length();
2240 return list.at( pos );
2245 parent->
setEvalErrorString( tr(
"[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName(
static_cast<QMetaType::Type
>(
container.userType() ) ) ) );
2257 bool resC = mContainer->prepare( parent, context );
2258 bool resV = mIndex->prepare( parent, context );
2259 return resC && resV;
2264 return u
"%1[%2]"_s.arg( mContainer->dump(), mIndex->dump() );
2270 return QSet< QString >();
2272 return mContainer->referencedColumns() + mIndex->referencedColumns();
2277 return mContainer->referencedVariables() + mIndex->referencedVariables();
2282 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
2287 QList<const QgsExpressionNode *> lst;
2289 lst += mContainer->nodes() + mIndex->nodes();
2295 return mContainer->needsGeometry() || mIndex->needsGeometry();
2307 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.
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
QgsExpressionNodeBetweenOperator(QgsExpressionNode *node, QgsExpressionNode *nodeLowerBound, QgsExpressionNode *nodeHigherBound, bool negate=false)
This node tests if the result of node is between the result of nodeLowerBound and nodeHigherBound nod...
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.
QgsExpressionNodeBinaryOperator::BinaryOperator op() const
Returns the binary operator.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QString text() const
Returns a the name of this operator without the operands.
QgsExpressionNodeBinaryOperator(QgsExpressionNodeBinaryOperator::BinaryOperator op, QgsExpressionNode *opLeft, QgsExpressionNode *opRight)
Binary combination of the left and the right with op.
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.
QgsExpressionNodeColumnRef(const QString &name)
Constructor for QgsExpressionNodeColumnRef, referencing the column with the specified name.
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.
QgsExpressionNode * thenExp() const
The expression node that makes the THEN result part of the condition.
QgsExpressionNode * whenExp() const
The expression that makes the WHEN part of the condition.
QgsExpressionNodeCondition::WhenThen * clone() const
Gets a deep copy of this WhenThen combination.
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.
QgsExpressionNode * elseExp() const
The ELSE expression used for the condition.
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.
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(QgsExpressionNode *node, QgsExpressionNode::NodeList *list, bool notin=false)
This node tests if the result of node is in the result of list.
~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.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
QgsExpressionNodeIndexOperator(QgsExpressionNode *container, QgsExpressionNode *index)
Constructor for QgsExpressionNodeIndexOperator.
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.
QgsExpressionNode * index() const
Returns the index node, representing an array element index or map key.
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.
QgsExpressionNode * container() const
Returns the container node, representing an array or map value.
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.
QgsExpressionNodeLiteral(const QVariant &value)
Constructor for QgsExpressionNodeLiteral, with the specified literal value.
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.
QgsExpressionNodeUnaryOperator(QgsExpressionNodeUnaryOperator::UnaryOperator op, QgsExpressionNode *operand)
A node unary operator is modifying the value of operand by negating it with op.
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.
virtual QString dump() const
Returns a string dump of the expression node.
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.
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.
virtual QgsExpressionNode * clone() const =0
Generate a clone of this node.
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.
QgsExpressionNode()=default
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.
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.