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