25#include <QRegularExpression>
29using namespace Qt::StringLiterals;
31const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] = {
33 "OR",
"AND",
"=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
"+",
"-",
"*",
"/",
"//",
"%",
"^",
"||"
36const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] = {
45 const QList< QgsExpressionNode * > nodeList = mList->list();
47 needs |= n->needsGeometry();
58 mList.append( node->
node );
59 mNameList.append( cleanNamedNodeName( node->
name ) );
60 mHasNamedNodes =
true;
69 nl->mList.append( node->clone() );
71 nl->mNameList = mNameList;
91QString QgsExpressionNode::NodeList::cleanNamedNodeName(
const QString &name )
93 QString cleaned = name.toLower();
96 if ( cleaned ==
"geom"_L1 )
97 cleaned = u
"geometry"_s;
98 else if ( cleaned ==
"val"_L1 )
100 else if ( cleaned ==
"geometry a"_L1 )
101 cleaned = u
"geometry1"_s;
102 else if ( cleaned ==
"geometry b"_L1 )
103 cleaned = u
"geometry2"_s;
104 else if ( cleaned ==
"i"_L1 )
105 cleaned = u
"vertex"_s;
115 QVariant val = mOperand->eval( parent, context );
122 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
124 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
128 if ( QgsExpressionUtils::isIntSafe( val ) )
129 return QVariant( -QgsExpressionUtils::getIntValue( val, parent ) );
130 else if ( QgsExpressionUtils::isDoubleSafe( val ) )
131 return QVariant( -QgsExpressionUtils::getDoubleValue( val, parent ) );
145 return mOperand->prepare( parent, context );
151 return u
"%1 ( %2 )"_s.arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
153 return u
"%1 %2"_s.arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
159 return QSet< QString >();
161 return mOperand->referencedColumns();
166 return mOperand->referencedVariables();
171 return mOperand->referencedFunctions();
176 QList<const QgsExpressionNode *> lst;
178 lst += mOperand->nodes();
184 return mOperand->needsGeometry();
196 return mOperand->
isStatic( parent, context );
201 return UNARY_OPERATOR_TEXT[mOp];
250QVariant QgsExpressionNodeBinaryOperator::compareNonNullValues( QgsExpression *parent,
const QgsExpressionContext *,
const QVariant &vL,
const QVariant &vR, BinaryOperator op )
252 if ( ( vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime ) )
254 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
256 QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
263 dL.setTimeSpec( Qt::UTC );
264 dR.setTimeSpec( Qt::UTC );
268 else if ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate ) )
270 const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
272 const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
276 else if ( ( vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime ) )
278 const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
280 const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
282 return compareOp<int>( dR.msecsTo( dL ), op ) ? TVL_True : TVL_False;
284 else if ( ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) && QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
288 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
290 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
295 else if ( vL.userType() == QMetaType::Type::Bool || vR.userType() == QMetaType::Type::Bool )
317 const bool vLBool = vL.toBool();
318 const bool vRBool = vR.toBool();
322 return vLBool == vRBool ? TVL_True : TVL_False;
324 return vLBool != vRBool ? TVL_True : TVL_False;
326 return vLBool < vRBool ? TVL_True : TVL_False;
328 return vLBool <= vRBool ? TVL_True : TVL_False;
330 return vLBool > vRBool ? TVL_True : TVL_False;
332 return vLBool >= vRBool ? TVL_True : TVL_False;
357 else if ( vL.userType() == qMetaTypeId< QgsInterval>() && vR.userType() == qMetaTypeId< QgsInterval>() )
359 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
361 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
368 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
370 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
372 int diff = QString::compare( sL, sR );
379 QVariant vL = mOpLeft->eval( parent, context );
384 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
386 if ( mOp ==
boAnd && tvlL == QgsExpressionUtils::False )
388 if ( mOp ==
boOr && tvlL == QgsExpressionUtils::True )
392 QVariant vR = mOpRight->eval( parent, context );
398 if ( vL.userType() == QMetaType::Type::QString && vR.userType() == QMetaType::Type::QString )
400 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
402 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
404 return QVariant( sL + sR );
413 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
415 else if ( mOp !=
boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
418 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
420 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
423 if ( mOp ==
boMod && iR == 0 )
426 return QVariant( computeInt( iL, iR ) );
428 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
430 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
432 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
436 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
439 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
442 && ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QTime ) || ( vR.userType() == QMetaType::Type::QDate && vL.userType() == QMetaType::Type::QTime ) ) )
444 QDate date = QgsExpressionUtils::getDateValue( vL.userType() == QMetaType::Type::QDate ? vL : vR, parent );
446 QTime time = QgsExpressionUtils::getTimeValue( vR.userType() == QMetaType::Type::QTime ? vR : vL, parent );
448 QDateTime dt = QDateTime( date, time );
449 return QVariant( dt );
451 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate )
453 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
455 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
457 return date1 - date2;
459 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime )
461 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
463 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
465 return time1 - time2;
467 else if ( mOp ==
boMinus && vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime )
469 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
471 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
478 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
480 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
482 if ( ( mOp ==
boDiv || mOp ==
boMod ) && fR == 0. )
484 return QVariant( computeDouble( fL, fR ) );
490 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
492 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
496 return QVariant( qlonglong( std::floor( fL / fR ) ) );
499 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
503 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
505 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
507 return QVariant( std::pow( fL, fR ) );
512 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
514 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
519 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
521 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
530 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
534 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
537 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
541 QVariantList lL = vL.toList();
542 QVariantList lR = vR.toList();
543 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
545 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
548 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
558 return QgsExpressionUtils::isNull( lR.at( i ) );
561 return QgsExpressionUtils::isNull( lL.at( i ) );
571 QVariant eq = eqNode.
eval( parent, context );
573 if ( eq == TVL_False )
577 QVariant v = node.
eval( parent, context );
587 return lL.length() == lR.length();
589 return lL.length() != lR.length();
591 return lL.length() < lR.length();
593 return lL.length() > lR.length();
595 return lL.length() <= lR.length();
597 return lL.length() >= lR.length();
605 return compareNonNullValues( parent, context, vL, vR, mOp );
611 const bool vLNull = QgsExpressionUtils::isNull( vL );
612 const bool vRNull = QgsExpressionUtils::isNull( vR );
613 if ( vLNull && vRNull )
614 return ( mOp ==
boIs ? TVL_True : TVL_False );
615 else if ( vLNull || vRNull )
616 return ( mOp ==
boIs ? TVL_False : TVL_True );
619 return compareNonNullValues( parent, context, vL, vR, mOp ==
boIs ?
boEQ :
boNE );
628 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
632 QString str = QgsExpressionUtils::getStringValue( vL, parent );
634 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
642 if ( esc_regexp.startsWith(
'%' ) )
644 esc_regexp.replace( 0, 1, u
".*"_s );
646 const thread_local QRegularExpression rx1( u
"[^\\\\](%)"_s );
648 while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
650 esc_regexp.replace( pos + 1, 1, u
".*"_s );
653 const thread_local QRegularExpression rx2( u
"\\\\%"_s );
654 esc_regexp.replace( rx2, u
"%"_s );
655 if ( esc_regexp.startsWith(
'_' ) )
657 esc_regexp.replace( 0, 1, u
"."_s );
659 const thread_local QRegularExpression rx3( u
"[^\\\\](_)"_s );
661 while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
663 esc_regexp.replace( pos + 1, 1,
'.' );
666 esc_regexp.replace(
"\\\\_"_L1,
"_"_L1 );
669 = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp ==
boLike || mOp ==
boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption )
675 matches = QRegularExpression( regexp ).match( str ).hasMatch();
683 return matches ? TVL_True : TVL_False;
687 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
691 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
693 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
695 return QVariant( sL + sR );
702qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
722QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d, QgsInterval *i )
727 return d.addSecs( i->
seconds() );
729 return d.addSecs( -i->
seconds() );
736double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
749 return std::fmod( x, y );
767 QMap<QString, QgsExpressionNode::NodeList> orValuesMap;
768 QList<QString> orFieldNames;
784 const QString fieldName =
op->opLeft()->dump();
785 if ( !orValuesMap.contains( fieldName ) )
787 orFieldNames.append( fieldName );
790 orValuesMap[fieldName].append(
op->opRight()->clone() );
795 const QString fieldName =
op->opRight()->dump();
796 if ( !orValuesMap.contains( fieldName ) )
798 orFieldNames.append( fieldName );
801 orValuesMap[fieldName].append(
op->opLeft()->clone() );
807 if ( visitOrNodes(
op->opLeft() ) && visitOrNodes(
op->opRight() ) )
819 const QString fieldName = inOp->node()->dump();
822 const auto nodes = inOp->list()->list();
823 for (
const auto &valueNode : std::as_const(
nodes ) )
831 if ( !orValuesMap.contains( fieldName ) )
833 orFieldNames.append( fieldName );
834 orValuesMap.insert( fieldName, *inOp->list()->clone() );
838 for (
const auto &valueNode : std::as_const(
nodes ) )
840 orValuesMap[fieldName].append( valueNode->clone() );
851 if ( visitOrNodes(
this ) && !orValuesMap.empty() )
853 std::unique_ptr<QgsExpressionNode> currentNode;
854 for (
const auto &fieldName : std::as_const( orFieldNames ) )
856 auto orValuesIt = orValuesMap.find( fieldName );
857 if ( orValuesIt.value().count() == 1 )
862 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>(
boOr, currentNode.release(), eqNode.release() );
866 currentNode = std::move( eqNode );
874 currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>(
boOr, currentNode.release(), inNode.release() );
878 currentNode = std::move( inNode );
891 bool resL = mOpLeft->prepare( parent, context );
892 bool resR = mOpRight->prepare( parent, context );
938 Q_ASSERT(
false &&
"unexpected binary operator" );
974 Q_ASSERT(
false &&
"unexpected binary operator" );
984 QString rdump( mOpRight->dump() );
989 rdump.prepend(
'(' ).append(
')' );
1006 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
1012 return QSet< QString >();
1014 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
1019 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
1024 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
1029 QList<const QgsExpressionNode *> lst;
1031 lst += mOpLeft->nodes() + mOpRight->nodes();
1037 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
1049 const bool leftStatic = mOpLeft->
isStatic( parent, context );
1050 const bool rightStatic = mOpRight->isStatic( parent, context );
1052 if ( leftStatic && rightStatic )
1064 mOpLeft->prepare( parent, context );
1065 if ( mOpLeft->hasCachedStaticValue() )
1067 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1068 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1076 else if ( rightStatic )
1078 mOpRight->prepare( parent, context );
1079 if ( mOpRight->hasCachedStaticValue() )
1081 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1082 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
1100 mOpLeft->prepare( parent, context );
1101 if ( mOpLeft->hasCachedStaticValue() )
1103 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
1104 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1112 else if ( rightStatic )
1114 mOpRight->prepare( parent, context );
1115 if ( mOpRight->hasCachedStaticValue() )
1117 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
1118 if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
1161 if ( mList->count() == 0 )
1162 return mNotIn ? TVL_True : TVL_False;
1163 QVariant v1 = mNode->eval( parent, context );
1165 if ( QgsExpressionUtils::isNull( v1 ) )
1168 bool listHasNull =
false;
1170 const QList< QgsExpressionNode * > nodeList = mList->list();
1173 QVariant v2 = n->eval( parent, context );
1175 if ( QgsExpressionUtils::isNull( v2 ) )
1181 if ( ( v1.userType() != QMetaType::Type::QString || v2.userType() != QMetaType::Type::QString ) && QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
1185 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
1187 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
1193 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
1195 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
1197 equal = QString::compare( s1, s2 ) == 0;
1201 return mNotIn ? TVL_False : TVL_True;
1209 return mNotIn ? TVL_True : TVL_False;
1222 bool res = mNode->prepare( parent, context );
1223 const QList< QgsExpressionNode * > nodeList = mList->list();
1226 res = res && n->prepare( parent, context );
1233 return u
"%1 %2 IN (%3)"_s.arg( mNode->dump(), mNotIn ?
"NOT" :
"", mList->dump() );
1245 if ( !mNode->isStatic( parent, context ) )
1248 const QList< QgsExpressionNode * > nodeList = mList->
list();
1251 if ( !n->isStatic( parent, context ) )
1262 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
1265 QVariant res = fd->
run( mArgs.get(), context, parent,
this );
1278 QMutexLocker locker( &QgsExpression::QgsExpression::sFunctionsMutex );
1281 const int functionParamsSize = functionParams.size();
1282 if ( functionParams.isEmpty() )
1285 mArgs.reset(
args );
1290 mArgs = std::make_unique<NodeList>();
1291 mArgs->reserve( functionParamsSize );
1300 mArgs = std::make_unique<NodeList>();
1301 mArgs->reserve( functionParamsSize );
1304 const QStringList argNames =
args->names();
1305 const QList<QgsExpressionNode *> argList =
args->list();
1308 const int argNamesSize = argNames.size();
1309 while ( idx < argNamesSize && argNames.at( idx ).isEmpty() )
1311 mArgs->append( argList.at( idx )->clone() );
1317 for ( ; idx < functionParamsSize; ++idx )
1320 int nodeIdx = argNames.indexOf( parameter.
name().toLower() );
1328 mArgs->append( argList.at( nodeIdx )->clone() );
1348 bool res = fd->
prepare(
this, parent, context );
1351 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1354 res = res && n->prepare( parent, context );
1364 return u
"%1%2"_s.arg( fd->
name(), fd->
name().startsWith(
'$' ) ? QString() : u
"()"_s );
1366 return u
"%1(%2)"_s.arg( fd->
name(), mArgs ? mArgs->dump() : QString() );
1372 return QSet< QString >();
1380 return functionColumns;
1384 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1387 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
1388 functionColumns.unite( n->referencedColumns() );
1392 return functionColumns;
1398 if ( fd->
name() ==
"var"_L1 )
1400 if ( !mArgs->list().isEmpty() )
1404 return QSet<QString>() << var->
value().toString();
1406 return QSet<QString>() << QString();
1410 QSet<QString> functionVariables = QSet<QString>();
1413 return functionVariables;
1415 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1418 functionVariables.unite( n->referencedVariables() );
1421 return functionVariables;
1428 QSet<QString> functions = QSet<QString>();
1429 functions.insert( fd->
name() );
1434 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1437 functions.unite( n->referencedFunctions() );
1444 QList<const QgsExpressionNode *> lst;
1449 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1459 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1462 const QList< QgsExpressionNode * > nodeList = mArgs->list();
1464 needs |= n->needsGeometry();
1483 if ( !
args || !
args->hasNamedNodes() )
1487 if ( functionParams.isEmpty() )
1494 QSet< int > providedArgs;
1495 QSet< int > handledArgs;
1498 while (
args->names().at( idx ).isEmpty() )
1500 providedArgs << idx;
1506 for ( ; idx < functionParams.count(); ++idx )
1508 int nodeIdx =
args->names().indexOf( functionParams.at( idx ).name().toLower() );
1511 if ( !functionParams.at( idx ).optional() )
1513 error = u
"No value specified for QgsExpressionFunction::Parameter '%1' for %2"_s.arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1519 if ( providedArgs.contains( idx ) )
1521 error = u
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2"_s.arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1525 providedArgs << idx;
1526 handledArgs << nodeIdx;
1531 const QStringList nameList =
args->names();
1532 for (
const QString &name : nameList )
1534 if ( !name.isEmpty() && !functionParams.contains( name ) )
1539 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1541 int functionIdx = functionParams.indexOf( name );
1542 if ( providedArgs.contains( functionIdx ) )
1544 error = u
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2"_s.arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1581 switch ( mValue.userType() )
1583 case QMetaType::Type::Int:
1584 return QString::number( mValue.toInt() );
1585 case QMetaType::Type::Double:
1587 case QMetaType::Type::LongLong:
1588 return QString::number( mValue.toLongLong() );
1589 case QMetaType::Type::QString:
1591 case QMetaType::Type::QTime:
1593 case QMetaType::Type::QDate:
1595 case QMetaType::Type::QDateTime:
1597 case QMetaType::Type::Bool:
1598 return mValue.toBool() ? u
"TRUE"_s : u
"FALSE"_s;
1600 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1611 return QSet<QString>();
1616 return QSet<QString>();
1621 return QSet<QString>();
1626 QList<const QgsExpressionNode *> lst;
1679 parent->
setEvalErrorString( tr(
"No feature available for field '%1' evaluation" ).arg( mName ) );
1716 const thread_local QRegularExpression re( u
"^[A-Za-z_\\x80-\\xff][A-Za-z0-9_\\x80-\\xff]*$"_s );
1717 const QRegularExpressionMatch match = re.match( mName );
1723 return QSet<QString>() << mName;
1728 return QSet<QString>();
1733 return QSet<QString>();
1738 QList<const QgsExpressionNode *> result;
1773 qDeleteAll( mConditions );
1783 for (
WhenThen *cond : std::as_const( mConditions ) )
1785 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1786 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1788 if ( tvl == QgsExpressionUtils::True )
1790 QVariant vRes = cond->mThenExp->eval( parent, context );
1798 QVariant vElse = mElseExp->eval( parent, context );
1809 bool foundAnyNonStaticConditions =
false;
1810 for (
WhenThen *cond : std::as_const( mConditions ) )
1812 const bool res = cond->mWhenExp->prepare( parent, context ) && cond->mThenExp->prepare( parent, context );
1816 foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
1817 if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
1821 if ( cond->mThenExp->hasCachedStaticValue() )
1840 const bool res = mElseExp->prepare( parent, context );
1844 if ( !foundAnyNonStaticConditions )
1847 if ( mElseExp->hasCachedStaticValue() )
1868 QString msg( u
"CASE"_s );
1869 for (
WhenThen *cond : mConditions )
1871 msg += u
" WHEN %1 THEN %2"_s.arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1874 msg += u
" ELSE %1"_s.arg( mElseExp->dump() );
1882 return QSet< QString >();
1885 for (
WhenThen *cond : mConditions )
1887 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1891 lst += mElseExp->referencedColumns();
1899 for (
WhenThen *cond : mConditions )
1901 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1905 lst += mElseExp->referencedVariables();
1913 for (
WhenThen *cond : mConditions )
1915 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1919 lst += mElseExp->referencedFunctions();
1926 QList<const QgsExpressionNode *> lst;
1928 for (
WhenThen *cond : mConditions )
1930 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1934 lst += mElseExp->nodes();
1941 for (
WhenThen *cond : mConditions )
1943 if ( cond->mWhenExp->needsGeometry() || cond->mThenExp->needsGeometry() )
1947 return mElseExp && mElseExp->needsGeometry();
1966 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1971 return mElseExp->
isStatic( parent, context );
1979 return QSet< QString >();
1981 QSet<QString> lst( mNode->referencedColumns() );
1982 const QList< QgsExpressionNode * > nodeList = mList->list();
1984 lst.unite( n->referencedColumns() );
1990 QSet<QString> lst( mNode->referencedVariables() );
1991 const QList< QgsExpressionNode * > nodeList = mList->list();
1993 lst.unite( n->referencedVariables() );
1999 QSet<QString> lst( mNode->referencedFunctions() );
2000 const QList< QgsExpressionNode * > nodeList = mList->list();
2002 lst.unite( n->referencedFunctions() );
2008 QList<const QgsExpressionNode *> lst;
2010 const QList< QgsExpressionNode * > nodeList = mList->list();
2027 bool res = mNode->prepare( parent, context );
2028 res = res && mLowerBound->prepare( parent, context );
2029 res = res && mHigherBound->prepare( parent, context );
2035 const QVariant nodeVal = mNode->eval( parent, context );
2044 const QVariant lowBoundValue = lowBound.
eval( parent, context );
2045 const bool lowBoundBool { lowBoundValue.toBool() };
2049 return QVariant( mNegate );
2053 const QVariant highBoundValue = highBound.
eval( parent, context );
2060 const bool highBoundBool { highBoundValue.toBool() };
2068 return QVariant( mNegate );
2077 return QVariant( mNegate );
2080 const bool res { lowBoundBool && highBoundBool };
2081 return mNegate ? QVariant( !res ) : QVariant( res );
2086 return u
"%1 %2 %3 AND %4"_s.arg( mNode->dump(), mNegate ? u
"NOT BETWEEN"_s : u
"BETWEEN"_s, mLowerBound->dump(), mHigherBound->dump() );
2091 QSet<QString> lst( mNode->referencedVariables() );
2092 lst.unite( mLowerBound->referencedVariables() );
2093 lst.unite( mHigherBound->referencedVariables() );
2099 QSet<QString> lst( mNode->referencedFunctions() );
2100 lst.unite( mLowerBound->referencedFunctions() );
2101 lst.unite( mHigherBound->referencedFunctions() );
2107 return {
this, mLowerBound.get(), mHigherBound.get() };
2112 QSet<QString> lst( mNode->referencedColumns() );
2113 lst.unite( mLowerBound->referencedColumns() );
2114 lst.unite( mHigherBound->referencedColumns() );
2120 if ( mNode->needsGeometry() )
2123 if ( mLowerBound->needsGeometry() )
2126 if ( mHigherBound->needsGeometry() )
2141 if ( !mNode->isStatic( parent, context ) )
2144 if ( !mLowerBound->isStatic( parent, context ) )
2147 if ( !mHigherBound->isStatic( parent, context ) )
2155 return mLowerBound.get();
2160 return mHigherBound.get();
2178 return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
2183 return BINARY_OPERATOR_TEXT[mOp];
2190 const QVariant
container = mContainer->eval( parent, context );
2192 const QVariant
index = mIndex->eval( parent, context );
2197 case QMetaType::Type::QVariantMap:
2198 return QgsExpressionUtils::getMapValue(
container, parent ).value(
index.toString() );
2200 case QMetaType::Type::QVariantList:
2201 case QMetaType::Type::QStringList:
2203 const QVariantList list = QgsExpressionUtils::getListValue(
container, parent );
2204 qlonglong pos = QgsExpressionUtils::getIntValue(
index, parent );
2205 if ( pos >= list.length() || pos < -list.length() )
2212 pos += list.length();
2215 return list.at( pos );
2220 parent->
setEvalErrorString( tr(
"[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName(
static_cast<QMetaType::Type
>(
container.userType() ) ) ) );
2232 bool resC = mContainer->prepare( parent, context );
2233 bool resV = mIndex->prepare( parent, context );
2234 return resC && resV;
2239 return u
"%1[%2]"_s.arg( mContainer->dump(), mIndex->dump() );
2245 return QSet< QString >();
2247 return mContainer->referencedColumns() + mIndex->referencedColumns();
2252 return mContainer->referencedVariables() + mIndex->referencedVariables();
2257 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
2262 QList<const QgsExpressionNode *> lst;
2264 lst += mContainer->nodes() + mIndex->nodes();
2270 return mContainer->needsGeometry() || mIndex->needsGeometry();
2282 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.