26#include <QRegularExpression> 
   28const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
 
   32  "=", 
"<>", 
"<=", 
">=", 
"<", 
">", 
"~", 
"LIKE", 
"NOT LIKE", 
"ILIKE", 
"NOT ILIKE", 
"IS", 
"IS NOT",
 
   33  "+", 
"-", 
"*", 
"/", 
"//", 
"%", 
"^",
 
   37const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
 
   46  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
   48    needs |= n->needsGeometry();
 
 
   59  mList.append( node->
node );
 
   60  mNameList.append( cleanNamedNodeName( node->
name ) );
 
   61  mHasNamedNodes = 
true;
 
 
   70    nl->mList.append( node->clone() );
 
   72  nl->mNameList = mNameList;
 
 
   83    if ( !first ) msg += QLatin1String( 
", " );
 
 
   90QString QgsExpressionNode::NodeList::cleanNamedNodeName( 
const QString &name )
 
   92  QString cleaned = name.toLower();
 
   95  if ( cleaned == QLatin1String( 
"geom" ) )
 
   96    cleaned = QStringLiteral( 
"geometry" );
 
   97  else if ( cleaned == QLatin1String( 
"val" ) )
 
   98    cleaned = QStringLiteral( 
"value" );
 
   99  else if ( cleaned == QLatin1String( 
"geometry a" ) )
 
  100    cleaned = QStringLiteral( 
"geometry1" );
 
  101  else if ( cleaned == QLatin1String( 
"geometry b" ) )
 
  102    cleaned = QStringLiteral( 
"geometry2" );
 
  103  else if ( cleaned == QLatin1String( 
"i" ) )
 
  104    cleaned = QStringLiteral( 
"vertex" );
 
  114  QVariant val = mOperand->eval( parent, context );
 
  121      QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
 
  123      return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
 
  127      if ( QgsExpressionUtils::isIntSafe( val ) )
 
  128        return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
 
  129      else if ( QgsExpressionUtils::isDoubleSafe( val ) )
 
  130        return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
 
 
  144  return mOperand->prepare( parent, context );
 
 
  150    return QStringLiteral( 
"%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
 
  152    return QStringLiteral( 
"%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
 
 
  158    return QSet< QString >();
 
  160  return mOperand->referencedColumns();
 
 
  165  return mOperand->referencedVariables();
 
 
  170  return mOperand->referencedFunctions();
 
 
  175  QList<const QgsExpressionNode *> lst;
 
  177  lst += mOperand->nodes();
 
 
  183  return mOperand->needsGeometry();
 
 
  195  return mOperand->
isStatic( parent, context );
 
 
  200  return UNARY_OPERATOR_TEXT[mOp];
 
 
  207  QVariant vL = mOpLeft->eval( parent, context );
 
  210  if ( mOp == boAnd || mOp == boOr )
 
  212    QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
 
  214    if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
 
  216    if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
 
  220  QVariant vR = mOpRight->eval( parent, context );
 
  226      if ( vL.userType() == QMetaType::Type::QString && vR.userType() == QMetaType::Type::QString )
 
  228        QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
 
  230        QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
 
  232        return QVariant( sL + sR );
 
  241      if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  243      else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
 
  246        qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
 
  248        qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
 
  251        if ( mOp == boMod && iR == 0 )
 
  254        return QVariant( computeInt( iL, iR ) );
 
  256      else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
 
  258        QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  260        QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
 
  262        if ( mOp == boDiv || mOp == boMul || mOp == boMod )
 
  264          parent->
setEvalErrorString( tr( 
"Can't perform /, *, or % on DateTime and Interval" ) );
 
  267        return QVariant( computeDateTimeFromInterval( dL, &iL ) );
 
  269      else if ( mOp == boPlus && ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QTime ) ||
 
  270                                   ( vR.userType() == QMetaType::Type::QDate && vL.userType() == QMetaType::Type::QTime ) ) )
 
  272        QDate date = QgsExpressionUtils::getDateValue( vL.userType() == QMetaType::Type::QDate ? vL : vR, parent );
 
  274        QTime time = QgsExpressionUtils::getTimeValue( vR.userType() == QMetaType::Type::QTime ? vR : vL, parent );
 
  276        QDateTime dt = QDateTime( date, time );
 
  277        return QVariant( dt );
 
  279      else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate )
 
  281        QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
 
  283        QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
 
  285        return date1 - date2;
 
  287      else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime )
 
  289        QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
 
  291        QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
 
  293        return time1 - time2;
 
  295      else if ( mOp == boMinus && vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime )
 
  297        QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  299        QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
 
  306        double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  308        double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  310        if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
 
  312        return QVariant( computeDouble( fL, fR ) );
 
  318      double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  320      double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  324      return QVariant( qlonglong( std::floor( fL / fR ) ) );
 
  327      if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  331        double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  333        double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  335        return QVariant( std::pow( fL, fR ) );
 
  340      QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
 
  342      return  QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
 
  347      QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
 
  349      return  QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
 
  358      if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  362      else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
 
  365        if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
 
  369        QVariantList lL = vL.toList();
 
  370        QVariantList lR = vR.toList();
 
  371        for ( 
int i = 0; i < lL.length() && i < lR.length(); i++ )
 
  373          if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
 
  376          if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
 
  386                return QgsExpressionUtils::isNull( lR.at( i ) );
 
  389                return QgsExpressionUtils::isNull( lL.at( i ) );
 
  399          QVariant eq = eqNode.
eval( parent, context );
 
  401          if ( eq == TVL_False )
 
  405            QVariant v = node.
eval( parent, context );
 
  415            return lL.length() == lR.length();
 
  417            return lL.length() != lR.length();
 
  419            return lL.length() < lR.length();
 
  421            return lL.length() > lR.length();
 
  423            return lL.length() <= lR.length();
 
  425            return lL.length() >= lR.length();
 
  431      else if ( ( vL.userType() == QMetaType::Type::QDateTime && vR.userType() == QMetaType::Type::QDateTime ) )
 
  433        QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  435        QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
 
  442        dL.setTimeSpec( Qt::UTC );
 
  443        dR.setTimeSpec( Qt::UTC );
 
  445        return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
 
  447      else if ( ( vL.userType() == QMetaType::Type::QDate && vR.userType() == QMetaType::Type::QDate ) )
 
  449        const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
 
  451        const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
 
  453        return compare( dR.daysTo( dL ) ) ? TVL_True : TVL_False;
 
  455      else if ( ( vL.userType() == QMetaType::Type::QTime && vR.userType() == QMetaType::Type::QTime ) )
 
  457        const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
 
  459        const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
 
  461        return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
 
  463      else if ( ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) &&
 
  464                QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
 
  468        double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  470        double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  472        return compare( fL - fR ) ? TVL_True : TVL_False;
 
  475      else if ( vL.userType() == QMetaType::Type::Bool || vR.userType() == QMetaType::Type::Bool )
 
  481        if ( vL.userType() == QMetaType::Type::Bool && vR.userType() == QMetaType::Type::Bool )
 
  482          return vL.toBool() == vR.toBool() ? TVL_True : TVL_False;
 
  487      else if ( vL.userType() == qMetaTypeId< QgsInterval>() && vR.userType() == qMetaTypeId< QgsInterval>() )
 
  489        double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
 
  491        double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
 
  493        return compare( fL - fR ) ? TVL_True : TVL_False;
 
  498        QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  500        QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  502        int diff = QString::compare( sL, sR );
 
  503        return compare( diff ) ? TVL_True : TVL_False;
 
  508      if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) ) 
 
  509        return ( mOp == boIs ? TVL_True : TVL_False );
 
  510      else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) ) 
 
  511        return ( mOp == boIs ? TVL_False : TVL_True );
 
  515        if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
 
  516             ( vL.userType() != QMetaType::Type::QString || vR.userType() != QMetaType::Type::QString ) )
 
  518          double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  520          double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  526          QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  528          QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  530          equal = QString::compare( sL, sR ) == 0;
 
  533          return mOp == boIs ? TVL_True : TVL_False;
 
  535          return mOp == boIs ? TVL_False : TVL_True;
 
  543      if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  547        QString str    = QgsExpressionUtils::getStringValue( vL, parent );
 
  549        QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
 
  553        if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) 
 
  557          if ( esc_regexp.startsWith( 
'%' ) )
 
  559            esc_regexp.replace( 0, 1, QStringLiteral( 
".*" ) );
 
  561          const thread_local QRegularExpression rx1( QStringLiteral( 
"[^\\\\](%)" ) );
 
  563          while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
 
  565            esc_regexp.replace( pos + 1, 1, QStringLiteral( 
".*" ) );
 
  568          const thread_local QRegularExpression rx2( QStringLiteral( 
"\\\\%" ) );
 
  569          esc_regexp.replace( rx2, QStringLiteral( 
"%" ) );
 
  570          if ( esc_regexp.startsWith( 
'_' ) )
 
  572            esc_regexp.replace( 0, 1, QStringLiteral( 
"." ) );
 
  574          const thread_local QRegularExpression rx3( QStringLiteral( 
"[^\\\\](_)" ) );
 
  576          while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
 
  578            esc_regexp.replace( pos + 1, 1, 
'.' );
 
  581          esc_regexp.replace( QLatin1String( 
"\\\\_" ), QLatin1String( 
"_" ) );
 
  583          matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp == boLike || mOp == boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption ).match( str ).hasMatch();
 
  587          matches = QRegularExpression( regexp ).match( str ).hasMatch();
 
  590        if ( mOp == boNotLike || mOp == boNotILike )
 
  595        return matches ? TVL_True : TVL_False;
 
  599      if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  603        QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  605        QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  607        return QVariant( sL + sR );
 
 
  614bool QgsExpressionNodeBinaryOperator::compare( 
double diff )
 
  636qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
 
  656QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval( 
const QDateTime &d, 
QgsInterval *i )
 
  661      return d.addSecs( i->
seconds() );
 
  663      return d.addSecs( -i->
seconds() );
 
  670double QgsExpressionNodeBinaryOperator::computeDouble( 
double x, 
double y )
 
  683      return std::fmod( x, y );
 
  703    QMap<QString, QgsExpressionNode::NodeList> orValuesMap;
 
  704    QList<QString> orFieldNames;
 
  711        if ( op->op() != boOr && op->op() != boEQ )
 
  716        if ( op->op() == boEQ )
 
  721            const QString fieldName = op->opLeft()->dump();
 
  722            if ( !orValuesMap.contains( fieldName ) )
 
  724              orFieldNames.append( fieldName );
 
  727            orValuesMap[fieldName].append( op->opRight()->clone() );
 
  732            const QString fieldName = op->opRight()->dump();
 
  733            if ( !orValuesMap.contains( fieldName ) )
 
  735              orFieldNames.append( fieldName );
 
  738            orValuesMap[fieldName].append( op->opLeft()->clone() );
 
  744        if ( visitOrNodes( op->opLeft() ) && visitOrNodes( op->opRight() ) )
 
  757        const QString fieldName = inOp->node()->dump();
 
  760        const auto nodes = inOp->list()->list();
 
  761        for ( 
const auto &valueNode : std::as_const( 
nodes ) )
 
  769        if ( !orValuesMap.contains( fieldName ) )
 
  771          orFieldNames.append( fieldName );
 
  772          orValuesMap.insert( fieldName, *inOp->list()->clone() );
 
  776          for ( 
const auto &valueNode : std::as_const( 
nodes ) )
 
  778            orValuesMap[fieldName].append( valueNode->clone() );
 
  789    if ( visitOrNodes( 
this ) && ! orValuesMap.empty() )
 
  792      std::unique_ptr<QgsExpressionNode> currentNode;
 
  793      for ( 
const auto &fieldName : std::as_const( orFieldNames ) )
 
  795        auto orValuesIt = orValuesMap.find( fieldName );
 
  796        if ( orValuesIt.value().count() == 1 )
 
  798          auto eqNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boEQ, 
new QgsExpressionNodeColumnRef( fieldName ), orValuesIt.value().at( 0 )->
clone() );
 
  801            currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), eqNode.release() );
 
  805            currentNode = std::move( eqNode );
 
  813            currentNode = std::make_unique<QgsExpressionNodeBinaryOperator>( boOr, currentNode.release(), inNode.release() );
 
  817            currentNode = std::move( inNode );
 
  831  bool resL = mOpLeft->prepare( parent, context );
 
  832  bool resR = mOpRight->prepare( parent, context );
 
 
  878  Q_ASSERT( 
false && 
"unexpected binary operator" );
 
 
  914  Q_ASSERT( 
false && 
"unexpected binary operator" );
 
 
  924  QString rdump( mOpRight->dump() );
 
  929    rdump.prepend( 
'(' ).append( 
')' );
 
  933  if ( leftAssociative() )
 
  935    fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral( 
"(%1)" ) : QStringLiteral( 
"%1" );
 
  936    fmt += QLatin1String( 
" %2 " );
 
  937    fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral( 
"(%3)" ) : QStringLiteral( 
"%3" );
 
  941    fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral( 
"(%1)" ) : QStringLiteral( 
"%1" );
 
  942    fmt += QLatin1String( 
" %2 " );
 
  943    fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral( 
"(%3)" ) : QStringLiteral( 
"%3" );
 
  946  return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
 
 
  952    return QSet< QString >();
 
  954  return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
 
 
  959  return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
 
 
  964  return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
 
 
  969  QList<const QgsExpressionNode *> lst;
 
  971  lst += mOpLeft->nodes() + mOpRight->nodes();
 
 
  977  return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
 
 
  989  const bool leftStatic = mOpLeft->
isStatic( parent, context );
 
  990  const bool rightStatic = mOpRight->isStatic( parent, context );
 
  992  if ( leftStatic && rightStatic )
 
 1004        mOpLeft->prepare( parent, context );
 
 1005        if ( mOpLeft->hasCachedStaticValue() )
 
 1007          QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
 
 1008          if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
 
 1016      else if ( rightStatic )
 
 1018        mOpRight->prepare( parent, context );
 
 1019        if ( mOpRight->hasCachedStaticValue() )
 
 1021          QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
 
 1022          if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
 
 1040        mOpLeft->prepare( parent, context );
 
 1041        if ( mOpLeft->hasCachedStaticValue() )
 
 1043          QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
 
 1044          if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
 
 1052      else if ( rightStatic )
 
 1054        mOpRight->prepare( parent, context );
 
 1055        if ( mOpRight->hasCachedStaticValue() )
 
 1057          QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
 
 1058          if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
 
 
 1101  if ( mList->count() == 0 )
 
 1102    return mNotIn ? TVL_True : TVL_False;
 
 1103  QVariant v1 = mNode->eval( parent, context );
 
 1105  if ( QgsExpressionUtils::isNull( v1 ) )
 
 1108  bool listHasNull = 
false;
 
 1110  const QList< QgsExpressionNode * > nodeList = mList->list();
 
 1113    QVariant v2 = n->eval( parent, context );
 
 1115    if ( QgsExpressionUtils::isNull( v2 ) )
 
 1121      if ( ( v1.userType() != QMetaType::Type::QString || v2.userType() != QMetaType::Type::QString ) &&
 
 1122           QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
 
 1126        double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
 
 1128        double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
 
 1134        QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
 
 1136        QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
 
 1138        equal = QString::compare( s1, s2 ) == 0;
 
 1142        return mNotIn ? TVL_False : TVL_True;
 
 1150    return mNotIn ? TVL_True : TVL_False;
 
 
 1166  bool res = mNode->prepare( parent, context );
 
 1167  const QList< QgsExpressionNode * > nodeList = mList->list();
 
 1170    res = res && n->prepare( parent, context );
 
 
 1177  return QStringLiteral( 
"%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ? 
"NOT" : 
"", mList->dump() );
 
 
 1189  if ( !mNode->isStatic( parent, context ) )
 
 1192  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1195    if ( !n->isStatic( parent, context ) )
 
 
 1206  QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
 
 1209  QVariant res = fd->
run( mArgs, context, parent, 
this );
 
 
 1217  : mFnIndex( fnIndex )
 
 1222  QMutexLocker locker( &QgsExpression::QgsExpression::sFunctionsMutex );
 
 1225  const int functionParamsSize = functionParams.size();
 
 1226  if ( functionParams.isEmpty() )
 
 1235    mArgs->
reserve( functionParamsSize );
 
 1245    mArgs->
reserve( functionParamsSize );
 
 1248    const QStringList argNames = 
args->
names();
 
 1249    const QList<QgsExpressionNode *> argList = 
args->
list();
 
 1252      const int argNamesSize = argNames.size();
 
 1253      while ( idx < argNamesSize && argNames.at( idx ).isEmpty() )
 
 1255        mArgs->
append( argList.at( idx )->clone() );
 
 1261    for ( ; idx < functionParamsSize; ++idx )
 
 1264      int nodeIdx = argNames.indexOf( parameter.
name().toLower() );
 
 1272        mArgs->
append( argList.at( nodeIdx )->clone() );
 
 
 1294  bool res = fd->
prepare( 
this, parent, context );
 
 1297    const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1300      res = res && n->prepare( parent, context );
 
 
 1310    return QStringLiteral( 
"%1%2" ).arg( fd->
name(), fd->
name().startsWith( 
'$' ) ? QString() : QStringLiteral( 
"()" ) ); 
 
 1312    return QStringLiteral( 
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->
dump() : QString() ); 
 
 
 1318    return QSet< QString >();
 
 1326    return functionColumns;
 
 1330  const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1333    if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
 
 1334      functionColumns.unite( n->referencedColumns() );
 
 1338  return functionColumns;
 
 
 1344  if ( fd->
name() == QLatin1String( 
"var" ) )
 
 1346    if ( !mArgs->
list().isEmpty() )
 
 1350        return QSet<QString>() << var->
value().toString();
 
 1352    return QSet<QString>() << QString();
 
 1356    QSet<QString> functionVariables = QSet<QString>();
 
 1359      return functionVariables;
 
 1361    const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1364      functionVariables.unite( n->referencedVariables() );
 
 1367    return functionVariables;
 
 
 1374  QSet<QString> functions = QSet<QString>();
 
 1375  functions.insert( fd->
name() );
 
 1380  const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1383    functions.unite( n->referencedFunctions() );
 
 
 1390  QList<const QgsExpressionNode *> lst;
 
 1395  const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 
 1405  bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry( 
this );
 
 1408    const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1410      needs |= n->needsGeometry();
 
 
 1433  if ( functionParams.isEmpty() )
 
 1440    QSet< int > providedArgs;
 
 1441    QSet< int > handledArgs;
 
 1444    while ( 
args->
names().at( idx ).isEmpty() )
 
 1446      providedArgs << idx;
 
 1452    for ( ; idx < functionParams.count(); ++idx )
 
 1454      int nodeIdx = 
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
 
 1457        if ( !functionParams.at( idx ).optional() )
 
 1459          error = QStringLiteral( 
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 1465        if ( providedArgs.contains( idx ) )
 
 1467          error = QStringLiteral( 
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 1471      providedArgs << idx;
 
 1472      handledArgs << nodeIdx;
 
 1477    const QStringList nameList = 
args->
names();
 
 1478    for ( 
const QString &name : nameList )
 
 1480      if ( !name.isEmpty() && !functionParams.contains( name ) )
 
 1485      if ( !name.isEmpty() && !handledArgs.contains( idx ) )
 
 1487        int functionIdx = functionParams.indexOf( name );
 
 1488        if ( providedArgs.contains( functionIdx ) )
 
 1490          error = QStringLiteral( 
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 
 1526    return QStringLiteral( 
"NULL" );
 
 1528  switch ( mValue.userType() )
 
 1530    case QMetaType::Type::Int:
 
 1531      return QString::number( mValue.toInt() );
 
 1532    case QMetaType::Type::Double:
 
 1533      return QString::number( mValue.toDouble() );
 
 1534    case QMetaType::Type::LongLong:
 
 1535      return QString::number( mValue.toLongLong() );
 
 1536    case QMetaType::Type::QString:
 
 1538    case QMetaType::Type::QTime:
 
 1540    case QMetaType::Type::QDate:
 
 1542    case QMetaType::Type::QDateTime:
 
 1544    case QMetaType::Type::Bool:
 
 1545      return mValue.toBool() ? QStringLiteral( 
"TRUE" ) : QStringLiteral( 
"FALSE" );
 
 1547      return tr( 
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
 
 
 1558  return QSet<QString>();
 
 
 1563  return QSet<QString>();
 
 
 1568  return QSet<QString>();
 
 
 1573  QList<const QgsExpressionNode *> lst;
 
 
 1626      parent->
setEvalErrorString( tr( 
"No feature available for field '%1' evaluation" ).arg( mName ) );
 
 
 1663  const thread_local QRegularExpression re( QStringLiteral( 
"^[A-Za-z_\\x80-\\xff][A-Za-z0-9_\\x80-\\xff]*$" ) );
 
 1664  const QRegularExpressionMatch match = re.match( mName );
 
 
 1670  return QSet<QString>() << mName;
 
 
 1675  return QSet<QString>();
 
 
 1680  return QSet<QString>();
 
 
 1685  QList<const QgsExpressionNode *> result;
 
 
 1712  : mConditions( *conditions )
 
 1713  , mElseExp( elseExp )
 
 
 1721  qDeleteAll( mConditions );
 
 
 1731  for ( 
WhenThen *cond : std::as_const( mConditions ) )
 
 1733    QVariant vWhen = cond->mWhenExp->eval( parent, context );
 
 1734    QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
 
 1736    if ( tvl == QgsExpressionUtils::True )
 
 1738      QVariant vRes = cond->mThenExp->eval( parent, context );
 
 1746    QVariant vElse = mElseExp->
eval( parent, context );
 
 
 1757  bool foundAnyNonStaticConditions = 
false;
 
 1758  for ( 
WhenThen *cond : std::as_const( mConditions ) )
 
 1760    const bool res = cond->mWhenExp->prepare( parent, context )
 
 1761                     && cond->mThenExp->prepare( parent, context );
 
 1765    foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
 
 1766    if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
 
 1770      if ( cond->mThenExp->hasCachedStaticValue() )
 
 1789    const bool res = mElseExp->
prepare( parent, context );
 
 1793    if ( !foundAnyNonStaticConditions )
 
 
 1817  QString msg( QStringLiteral( 
"CASE" ) );
 
 1818  for ( 
WhenThen *cond : mConditions )
 
 1820    msg += QStringLiteral( 
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
 
 1823    msg += QStringLiteral( 
" ELSE %1" ).arg( mElseExp->
dump() );
 
 1824  msg += QLatin1String( 
" END" );
 
 
 1831    return QSet< QString >();
 
 1834  for ( 
WhenThen *cond : mConditions )
 
 1836    lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
 
 
 1848  for ( 
WhenThen *cond : mConditions )
 
 1850    lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
 
 
 1862  for ( 
WhenThen *cond : mConditions )
 
 1864    lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
 
 
 1875  QList<const QgsExpressionNode *> lst;
 
 1877  for ( 
WhenThen *cond : mConditions )
 
 1879    lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
 
 1883    lst += mElseExp->
nodes();
 
 
 1890  for ( 
WhenThen *cond : mConditions )
 
 1892    if ( cond->mWhenExp->needsGeometry() ||
 
 1893         cond->mThenExp->needsGeometry() )
 
 
 1916    if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
 
 1921    return mElseExp->
isStatic( parent, context );
 
 
 1929    return QSet< QString >();
 
 1932  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1934    lst.unite( n->referencedColumns() );
 
 
 1941  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1943    lst.unite( n->referencedVariables() );
 
 
 1950  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1952    lst.unite( n->referencedFunctions() );
 
 
 1958  QList<const QgsExpressionNode *> lst;
 
 1960  const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 
 1971  delete mHigherBound;
 
 
 1981  bool res = mNode->
prepare( parent, context );
 
 1982  res = res && mLowerBound->
prepare( parent, context );
 
 1983  res = res && mHigherBound->
prepare( parent, context );
 
 
 1989  const QVariant nodeVal = mNode->
eval( parent, context );
 
 1998  const QVariant lowBoundValue = lowBound.
eval( parent, context );
 
 1999  const bool lowBoundBool { lowBoundValue.toBool() };
 
 2003    return QVariant( mNegate );
 
 2007  const QVariant highBoundValue = highBound.
eval( parent, context );
 
 2014  const bool highBoundBool { highBoundValue.toBool() };
 
 2024      return QVariant( mNegate );
 
 2034    return QVariant( mNegate );
 
 2037  const bool res { lowBoundBool &&highBoundBool };
 
 2038  return mNegate ? QVariant( ! res ) : QVariant( res );
 
 
 2044  return QStringLiteral( 
"%1 %2 %3 AND %4" ).arg( mNode->
dump(), mNegate ? QStringLiteral( 
"NOT BETWEEN" ) : QStringLiteral( 
"BETWEEN" ), mLowerBound->
dump(), mHigherBound->
dump() );
 
 
 2065  return { 
this, mLowerBound, mHigherBound };
 
 
 2099  if ( !mNode->
isStatic( parent, context ) )
 
 2102  if ( !mLowerBound->
isStatic( parent, context ) )
 
 2105  if ( !mHigherBound->
isStatic( parent, context ) )
 
 
 2118  return mHigherBound;
 
 
 2127  : mWhenExp( whenExp )
 
 2128  , mThenExp( thenExp )
 
 
 2140  return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
 
 
 2145  return BINARY_OPERATOR_TEXT[mOp];
 
 
 2152  const QVariant container = mContainer->eval( parent, context );
 
 2154  const QVariant index = mIndex->eval( parent, context );
 
 2157  switch ( container.userType() )
 
 2159    case QMetaType::Type::QVariantMap:
 
 2160      return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
 
 2162    case QMetaType::Type::QVariantList:
 
 2163    case QMetaType::Type::QStringList:
 
 2165      const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
 
 2166      qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
 
 2167      if ( pos >= list.length() || pos < -list.length() )
 
 2174        pos += list.length();
 
 2177      return list.at( pos );
 
 2182        parent->
setEvalErrorString( tr( 
"[] can only be used with map or array values, not %1" ).arg( QMetaType::typeName( 
static_cast<QMetaType::Type
>( container.userType() ) ) ) );
 
 
 2194  bool resC = mContainer->prepare( parent, context );
 
 2195  bool resV = mIndex->prepare( parent, context );
 
 2196  return resC && resV;
 
 
 2201  return QStringLiteral( 
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
 
 
 2207    return QSet< QString >();
 
 2209  return mContainer->referencedColumns() + mIndex->referencedColumns();
 
 
 2214  return mContainer->referencedVariables() + mIndex->referencedVariables();
 
 
 2219  return mContainer->referencedFunctions() + mIndex->referencedFunctions();
 
 
 2224  QList<const QgsExpressionNode *> lst;
 
 2226  lst += mContainer->nodes() + mIndex->nodes();
 
 
 2232  return mContainer->needsGeometry() || mIndex->needsGeometry();
 
 
 2244  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.
 
A abstract base class for defining QgsExpression functions.
 
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
 
int params() const
The number of parameters this function takes.
 
bool lazyEval() const
true if this function should use lazy evaluation.
 
QString name() const
The name of the function.
 
virtual QVariant run(QgsExpressionNode::NodeList *args, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction *node)
Evaluates the function, first evaluating all required arguments before passing them to the function's...
 
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
 
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
 
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
 
SQL-like BETWEEN and NOT BETWEEN predicates.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
bool negate() const
Returns true if the predicate is an exclusion test (NOT BETWEEN).
 
QgsExpressionNode * lowerBound() const
Returns the lower bound expression node of the range.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QgsExpressionNode * higherBound() const
Returns the higher bound expression node of the range.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
~QgsExpressionNodeBetweenOperator() override
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
A binary expression operator, which operates on two values.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
bool leftAssociative() const
Returns true if the operator is left-associative.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
int precedence() const
Returns the precedence index for the operator.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QString text() const
Returns a the name of this operator without the operands.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
An expression node which takes it value from a feature's field.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
Represents a "WHEN... THEN..." portation of a CASE WHEN clause in an expression.
 
WhenThen(QgsExpressionNode *whenExp, QgsExpressionNode *thenExp)
A combination of when and then.
 
QgsExpressionNodeCondition::WhenThen * clone() const
Gets a deep copy of this WhenThen combination.
 
An expression node for CASE WHEN clauses.
 
QList< QgsExpressionNodeCondition::WhenThen * > WhenThenList
 
QgsExpressionNodeCondition(QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp=nullptr)
Create a new node with the given list of conditions and an optional elseExp expression.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
WhenThenList conditions() const
The list of WHEN THEN expression parts of the expression.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
~QgsExpressionNodeCondition() override
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
An expression node for expression functions.
 
int fnIndex() const
Returns the index of the node's function.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
~QgsExpressionNodeFunction() override
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QgsExpressionNodeFunction(int fnIndex, QgsExpressionNode::NodeList *args)
A function node consists of an index of the function in the global function array and a list of argum...
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
static bool validateParams(int fnIndex, QgsExpressionNode::NodeList *args, QString &error)
Tests whether the provided argument list is valid for the matching function.
 
An expression node for value IN or NOT IN clauses.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
~QgsExpressionNodeInOperator() override
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QgsExpressionNode::NodeList * list() const
Returns the list of nodes to search for matching values within.
 
A indexing expression operator, which allows use of square brackets [] to reference map and array ite...
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
An expression node for literal values.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QString valueAsString() const
Returns a string representation of the node's literal value.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QVariant value() const
The value of the literal.
 
A unary node is either negative as in boolean (not) or as in numbers (minus).
 
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
 
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
 
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
 
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
 
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
 
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
 
QString text() const
Returns a the name of this operator without the operands.
 
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
 
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
 
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
QgsExpressionNode * clone() const override
Generate a clone of this node.
 
QString dump() const override
Dump this node into a serialized (part) of an expression.
 
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
 
A list of expression nodes.
 
bool hasNamedNodes() const
Returns true if list contains any named nodes.
 
virtual QString dump() const
Returns a string dump of the expression node.
 
QStringList names() const
Returns a list of names for nodes.
 
QgsExpressionNode::NodeList * clone() const
Creates a deep copy of this list. Ownership is transferred to the caller.
 
void append(QgsExpressionNode *node)
Takes ownership of the provided node.
 
void reserve(int size)
Reserves size for the node list.
 
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
 
Abstract base class for all nodes that can appear in an expression.
 
bool hasCachedStaticValue() const
Returns true if the node can be replaced by a static cached value.
 
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
 
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.
 
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
Returns true if this node can be evaluated for a static value.
 
bool prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
 
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node.
 
bool mHasCachedValue
true if the node has a static, precalculated value.
 
const QgsExpressionNode * effectiveNode() const
Returns a reference to the simplest node which represents this node, after any compilation optimizati...
 
QVariant cachedStaticValue() const
Returns the node's static cached value.
 
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
 
QVariant mCachedStaticValue
Contains the static, precalculated value for the node if mHasCachedValue is true.
 
std::unique_ptr< QgsExpressionNode > mCompiledSimplifiedNode
Contains a compiled node which represents a simplified version of this node as a result of compilatio...
 
NodeType
Known node types.
 
@ ntBetweenOperator
Between operator.
 
@ ntIndexOperator
Index operator.
 
virtual bool needsGeometry() const =0
Abstract virtual method which returns if the geometry is required to evaluate this expression.
 
virtual QList< const QgsExpressionNode * > nodes() const =0
Returns a list of all nodes which are used in this expression.
 
void cloneTo(QgsExpressionNode *target) const
Copies the members of this node to the node provided in target.
 
virtual QSet< QString > referencedFunctions() const =0
Returns a set of all functions which are used in this expression.
 
Class for 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.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
#define ENSURE_NO_EVAL_ERROR
 
#define SET_EVAL_ERROR(x)
 
QgsExpressionNode * node
Node.