24 #include <QRegularExpression> 
   26 const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
 
   30   "=", 
"<>", 
"<=", 
">=", 
"<", 
">", 
"~", 
"LIKE", 
"NOT LIKE", 
"ILIKE", 
"NOT ILIKE", 
"IS", 
"IS NOT",
 
   31   "+", 
"-", 
"*", 
"/", 
"//", 
"%", 
"^",
 
   35 const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
 
   44   const QList< QgsExpressionNode * > nodeList = mList->
list();
 
   46     needs |= n->needsGeometry();
 
   57   mList.append( node->
node );
 
   58   mNameList.append( cleanNamedNodeName( node->
name ) );
 
   59   mHasNamedNodes = 
true;
 
   68     nl->mList.append( node->clone() );
 
   70   nl->mNameList = mNameList;
 
   81     if ( !first ) msg += QLatin1String( 
", " );
 
   88 QString QgsExpressionNode::NodeList::cleanNamedNodeName( 
const QString &name )
 
   90   QString cleaned = name.toLower();
 
   93   if ( cleaned == QLatin1String( 
"geom" ) )
 
   94     cleaned = QStringLiteral( 
"geometry" );
 
   95   else if ( cleaned == QLatin1String( 
"val" ) )
 
   96     cleaned = QStringLiteral( 
"value" );
 
   97   else if ( cleaned == QLatin1String( 
"geometry a" ) )
 
   98     cleaned = QStringLiteral( 
"geometry1" );
 
   99   else if ( cleaned == QLatin1String( 
"geometry b" ) )
 
  100     cleaned = QStringLiteral( 
"geometry2" );
 
  110   QVariant val = mOperand->eval( parent, context );
 
  117       QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
 
  119       return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
 
  123       if ( QgsExpressionUtils::isIntSafe( val ) )
 
  124         return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
 
  125       else if ( QgsExpressionUtils::isDoubleSafe( val ) )
 
  126         return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
 
  140   return mOperand->prepare( parent, context );
 
  146     return QStringLiteral( 
"%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
 
  148     return QStringLiteral( 
"%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
 
  154     return QSet< QString >();
 
  156   return mOperand->referencedColumns();
 
  161   return mOperand->referencedVariables();
 
  166   return mOperand->referencedFunctions();
 
  171   QList<const QgsExpressionNode *> lst;
 
  173   lst += mOperand->nodes();
 
  179   return mOperand->needsGeometry();
 
  191   return mOperand->isStatic( parent, context );
 
  196   return UNARY_OPERATOR_TEXT[mOp];
 
  203   QVariant vL = mOpLeft->eval( parent, context );
 
  206   if ( mOp == boAnd || mOp == boOr )
 
  208     QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
 
  210     if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
 
  212     if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
 
  216   QVariant vR = mOpRight->eval( parent, context );
 
  222       if ( vL.type() == QVariant::String && vR.type() == QVariant::String )
 
  224         QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
 
  226         QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
 
  228         return QVariant( sL + sR );
 
  237       if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  239       else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
 
  242         qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
 
  244         qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
 
  247         if ( mOp == boMod && iR == 0 )
 
  250         return QVariant( computeInt( iL, iR ) );
 
  252       else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
 
  254         QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  256         QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
 
  258         if ( mOp == boDiv || mOp == boMul || mOp == boMod )
 
  260           parent->
setEvalErrorString( tr( 
"Can't perform /, *, or % on DateTime and Interval" ) );
 
  263         return QVariant( computeDateTimeFromInterval( dL, &iL ) );
 
  265       else if ( mOp == boPlus && ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Time ) ||
 
  266                                    ( vR.type() == QVariant::Date && vL.type() == QVariant::Time ) ) )
 
  268         QDate date = QgsExpressionUtils::getDateValue( vL.type() == QVariant::Date ? vL : vR, parent );
 
  270         QTime time = QgsExpressionUtils::getTimeValue( vR.type() == QVariant::Time ? vR : vL, parent );
 
  272         QDateTime dt = QDateTime( date, time );
 
  273         return QVariant( dt );
 
  275       else if ( mOp == boMinus && vL.type() == QVariant::Date && vR.type() == QVariant::Date )
 
  277         QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
 
  279         QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
 
  281         return date1 - date2;
 
  283       else if ( mOp == boMinus && vL.type() == QVariant::Time && vR.type() == QVariant::Time )
 
  285         QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
 
  287         QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
 
  289         return time1 - time2;
 
  291       else if ( mOp == boMinus && vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime )
 
  293         QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  295         QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
 
  297         return datetime1 - datetime2;
 
  302         double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  304         double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  306         if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
 
  308         return QVariant( computeDouble( fL, fR ) );
 
  314       double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  316       double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  320       return QVariant( qlonglong( std::floor( fL / fR ) ) );
 
  323       if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  327         double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  329         double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  331         return QVariant( std::pow( fL, fR ) );
 
  336       QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
 
  338       return  QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
 
  343       QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
 
  345       return  QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
 
  354       if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  358       else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
 
  361         if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
 
  365         QVariantList lL = vL.toList();
 
  366         QVariantList lR = vR.toList();
 
  367         for ( 
int i = 0; i < lL.length() && i < lR.length(); i++ )
 
  369           if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
 
  372           if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
 
  382                 return QgsExpressionUtils::isNull( lR.at( i ) );
 
  385                 return QgsExpressionUtils::isNull( lL.at( i ) );
 
  395           QVariant eq = eqNode.
eval( parent, context );
 
  397           if ( eq == TVL_False )
 
  401             QVariant v = node.
eval( parent, context );
 
  411             return lL.length() == lR.length();
 
  413             return lL.length() != lR.length();
 
  415             return lL.length() < lR.length();
 
  417             return lL.length() > lR.length();
 
  419             return lL.length() <= lR.length();
 
  421             return lL.length() >= lR.length();
 
  427       else if ( ( vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime ) )
 
  429         QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
 
  431         QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
 
  438         dL.setTimeSpec( Qt::UTC );
 
  439         dR.setTimeSpec( Qt::UTC );
 
  441         return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
 
  443       else if ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Date ) )
 
  445         const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
 
  447         const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
 
  449         return compare( dR.daysTo( dL ) ) ? TVL_True : TVL_False;
 
  451       else if ( ( vL.type() == QVariant::Time && vR.type() == QVariant::Time ) )
 
  453         const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
 
  455         const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
 
  457         return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
 
  459       else if ( ( vL.type() != QVariant::String || vR.type() != QVariant::String ) &&
 
  460                 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
 
  464         double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  466         double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  468         return compare( fL - fR ) ? TVL_True : TVL_False;
 
  473         double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
 
  475         double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
 
  477         return compare( fL - fR ) ? TVL_True : TVL_False;
 
  482         QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  484         QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  486         int diff = QString::compare( sL, sR );
 
  487         return compare( diff ) ? TVL_True : TVL_False;
 
  492       if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) ) 
 
  493         return ( mOp == boIs ? TVL_True : TVL_False );
 
  494       else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) ) 
 
  495         return ( mOp == boIs ? TVL_False : TVL_True );
 
  499         if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
 
  500              ( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
 
  502           double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
 
  504           double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
 
  510           QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  512           QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  514           equal = QString::compare( sL, sR ) == 0;
 
  517           return mOp == boIs ? TVL_True : TVL_False;
 
  519           return mOp == boIs ? TVL_False : TVL_True;
 
  527       if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  531         QString 
str    = QgsExpressionUtils::getStringValue( vL, parent );
 
  533         QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
 
  537         if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike ) 
 
  541           if ( esc_regexp.startsWith( 
'%' ) )
 
  543             esc_regexp.replace( 0, 1, QStringLiteral( 
".*" ) );
 
  545           const thread_local QRegularExpression rx1( QStringLiteral( 
"[^\\\\](%)" ) );
 
  547           while ( ( pos = esc_regexp.indexOf( rx1, pos ) ) != -1 )
 
  549             esc_regexp.replace( pos + 1, 1, QStringLiteral( 
".*" ) );
 
  552           const thread_local QRegularExpression rx2( QStringLiteral( 
"\\\\%" ) );
 
  553           esc_regexp.replace( rx2, QStringLiteral( 
"%" ) );
 
  554           if ( esc_regexp.startsWith( 
'_' ) )
 
  556             esc_regexp.replace( 0, 1, QStringLiteral( 
"." ) );
 
  558           const thread_local QRegularExpression rx3( QStringLiteral( 
"[^\\\\](_)" ) );
 
  560           while ( ( pos = esc_regexp.indexOf( rx3, pos ) ) != -1 )
 
  562             esc_regexp.replace( pos + 1, 1, 
'.' );
 
  565           esc_regexp.replace( QLatin1String( 
"\\\\_" ), QLatin1String( 
"_" ) );
 
  567           matches = QRegularExpression( QRegularExpression::anchoredPattern( esc_regexp ), mOp == boLike || mOp == boNotLike ? QRegularExpression::DotMatchesEverythingOption : QRegularExpression::DotMatchesEverythingOption | QRegularExpression::CaseInsensitiveOption ).match( 
str ).hasMatch();
 
  571           matches = QRegularExpression( regexp ).match( 
str ).hasMatch();
 
  574         if ( mOp == boNotLike || mOp == boNotILike )
 
  579         return matches ? TVL_True : TVL_False;
 
  583       if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
 
  587         QString sL = QgsExpressionUtils::getStringValue( vL, parent );
 
  589         QString sR = QgsExpressionUtils::getStringValue( vR, parent );
 
  591         return QVariant( sL + sR );
 
  598 bool QgsExpressionNodeBinaryOperator::compare( 
double diff )
 
  620 qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
 
  640 QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval( 
const QDateTime &d, 
QgsInterval *i )
 
  645       return d.addSecs( i->
seconds() );
 
  647       return d.addSecs( -i->
seconds() );
 
  654 double QgsExpressionNodeBinaryOperator::computeDouble( 
double x, 
double y )
 
  667       return std::fmod( x, y );
 
  681   bool resL = mOpLeft->prepare( parent, context );
 
  682   bool resR = mOpRight->prepare( parent, context );
 
  728   Q_ASSERT( 
false && 
"unexpected binary operator" );
 
  764   Q_ASSERT( 
false && 
"unexpected binary operator" );
 
  774   QString rdump( mOpRight->dump() );
 
  779     rdump.prepend( 
'(' ).append( 
')' );
 
  783   if ( leftAssociative() )
 
  785     fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral( 
"(%1)" ) : QStringLiteral( 
"%1" );
 
  786     fmt += QLatin1String( 
" %2 " );
 
  787     fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral( 
"(%3)" ) : QStringLiteral( 
"%3" );
 
  791     fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral( 
"(%1)" ) : QStringLiteral( 
"%1" );
 
  792     fmt += QLatin1String( 
" %2 " );
 
  793     fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral( 
"(%3)" ) : QStringLiteral( 
"%3" );
 
  796   return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
 
  802     return QSet< QString >();
 
  804   return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
 
  809   return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
 
  814   return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
 
  819   QList<const QgsExpressionNode *> lst;
 
  821   lst += mOpLeft->nodes() + mOpRight->nodes();
 
  827   return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
 
  839   const bool leftStatic = mOpLeft->isStatic( parent, context );
 
  840   const bool rightStatic = mOpRight->isStatic( parent, context );
 
  842   if ( leftStatic && rightStatic )
 
  854         mOpLeft->prepare( parent, context );
 
  855         if ( mOpLeft->hasCachedStaticValue() )
 
  857           QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
 
  858           if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
 
  866       else if ( rightStatic )
 
  868         mOpRight->prepare( parent, context );
 
  869         if ( mOpRight->hasCachedStaticValue() )
 
  871           QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
 
  872           if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::True )
 
  890         mOpLeft->prepare( parent, context );
 
  891         if ( mOpLeft->hasCachedStaticValue() )
 
  893           QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpLeft->cachedStaticValue(), parent );
 
  894           if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
 
  902       else if ( rightStatic )
 
  904         mOpRight->prepare( parent, context );
 
  905         if ( mOpRight->hasCachedStaticValue() )
 
  907           QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( mOpRight->cachedStaticValue(), parent );
 
  908           if ( !parent->
hasEvalError() && tvl == QgsExpressionUtils::False )
 
  951   if ( mList->count() == 0 )
 
  952     return mNotIn ? TVL_True : TVL_False;
 
  953   QVariant v1 = mNode->eval( parent, context );
 
  955   if ( QgsExpressionUtils::isNull( v1 ) )
 
  958   bool listHasNull = 
false;
 
  960   const QList< QgsExpressionNode * > nodeList = mList->list();
 
  963     QVariant v2 = n->eval( parent, context );
 
  965     if ( QgsExpressionUtils::isNull( v2 ) )
 
  971       if ( ( v1.type() != QVariant::String || v2.type() != QVariant::String ) &&
 
  972            QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
 
  976         double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
 
  978         double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
 
  984         QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
 
  986         QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
 
  988         equal = QString::compare( s1, s2 ) == 0;
 
  992         return mNotIn ? TVL_False : TVL_True;
 
 1000     return mNotIn ? TVL_True : TVL_False;
 
 1016   bool res = mNode->prepare( parent, context );
 
 1017   const QList< QgsExpressionNode * > nodeList = mList->list();
 
 1020     res = res && n->prepare( parent, context );
 
 1027   return QStringLiteral( 
"%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ? 
"NOT" : 
"", mList->dump() );
 
 1039   if ( !mNode->isStatic( parent, context ) )
 
 1042   const QList< QgsExpressionNode * > nodeList = mList->list();
 
 1045     if ( !n->isStatic( parent, context ) )
 
 1056   QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
 
 1059   QVariant res = fd->
run( mArgs, context, parent, 
this );
 
 1067   : mFnIndex( fnIndex )
 
 1070   if ( functionParams.isEmpty() )
 
 1091     while ( idx < args->names().size() && 
args->
names().at( idx ).isEmpty() )
 
 1098     for ( ; idx < functionParams.count(); ++idx )
 
 1100       int nodeIdx = 
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
 
 1130   bool res = fd->
prepare( 
this, parent, context );
 
 1133     const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1136       res = res && n->prepare( parent, context );
 
 1146     return QStringLiteral( 
"%1%2" ).arg( fd->
name(), fd->
name().startsWith( 
'$' ) ? QString() : QStringLiteral( 
"()" ) ); 
 
 1148     return QStringLiteral( 
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->
dump() : QString() ); 
 
 1154     return QSet< QString >();
 
 1162     return functionColumns;
 
 1166   const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1169     if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
 
 1170       functionColumns.unite( n->referencedColumns() );
 
 1174   return functionColumns;
 
 1180   if ( fd->
name() == QLatin1String( 
"var" ) )
 
 1182     if ( !mArgs->
list().isEmpty() )
 
 1186         return QSet<QString>() << var->
value().toString();
 
 1188     return QSet<QString>() << QString();
 
 1192     QSet<QString> functionVariables = QSet<QString>();
 
 1195       return functionVariables;
 
 1197     const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1200       functionVariables.unite( n->referencedVariables() );
 
 1203     return functionVariables;
 
 1210   QSet<QString> functions = QSet<QString>();
 
 1211   functions.insert( fd->
name() );
 
 1216   const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1219     functions.unite( n->referencedFunctions() );
 
 1226   QList<const QgsExpressionNode *> lst;
 
 1231   const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1241   bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry( 
this );
 
 1244     const QList< QgsExpressionNode * > nodeList = mArgs->
list();
 
 1246       needs |= n->needsGeometry();
 
 1269   if ( functionParams.isEmpty() )
 
 1276     QSet< int > providedArgs;
 
 1277     QSet< int > handledArgs;
 
 1280     while ( 
args->
names().at( idx ).isEmpty() )
 
 1282       providedArgs << idx;
 
 1288     for ( ; idx < functionParams.count(); ++idx )
 
 1290       int nodeIdx = 
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
 
 1293         if ( !functionParams.at( idx ).optional() )
 
 1295           error = QStringLiteral( 
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 1301         if ( providedArgs.contains( idx ) )
 
 1303           error = QStringLiteral( 
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 1307       providedArgs << idx;
 
 1308       handledArgs << nodeIdx;
 
 1313     const QStringList nameList = 
args->
names();
 
 1314     for ( 
const QString &name : nameList )
 
 1316       if ( !name.isEmpty() && !functionParams.contains( name ) )
 
 1321       if ( !name.isEmpty() && !handledArgs.contains( idx ) )
 
 1323         int functionIdx = functionParams.indexOf( name );
 
 1324         if ( providedArgs.contains( functionIdx ) )
 
 1326           error = QStringLiteral( 
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(), 
QgsExpression::Functions()[
fnIndex]->name() );
 
 1361   if ( mValue.isNull() )
 
 1362     return QStringLiteral( 
"NULL" );
 
 1364   switch ( mValue.type() )
 
 1367       return QString::number( mValue.toInt() );
 
 1368     case QVariant::Double:
 
 1369       return QString::number( mValue.toDouble() );
 
 1370     case QVariant::LongLong:
 
 1371       return QString::number( mValue.toLongLong() );
 
 1372     case QVariant::String:
 
 1374     case QVariant::Bool:
 
 1375       return mValue.toBool() ? QStringLiteral( 
"TRUE" ) : QStringLiteral( 
"FALSE" );
 
 1377       return tr( 
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
 
 1388   return QSet<QString>();
 
 1393   return QSet<QString>();
 
 1398   return QSet<QString>();
 
 1403   QList<const QgsExpressionNode *> lst;
 
 1456       parent->
setEvalErrorString( tr( 
"No feature available for field '%1' evaluation" ).arg( mName ) );
 
 1493   const thread_local QRegularExpression re( QStringLiteral( 
"^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ) );
 
 1494   const QRegularExpressionMatch match = re.match( mName );
 
 1500   return QSet<QString>() << mName;
 
 1505   return QSet<QString>();
 
 1510   return QSet<QString>();
 
 1515   QList<const QgsExpressionNode *> result;
 
 1542   : mConditions( *conditions )
 
 1543   , mElseExp( elseExp )
 
 1551   qDeleteAll( mConditions );
 
 1561   for ( 
WhenThen *cond : std::as_const( mConditions ) )
 
 1563     QVariant vWhen = cond->mWhenExp->eval( parent, context );
 
 1564     QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
 
 1566     if ( tvl == QgsExpressionUtils::True )
 
 1568       QVariant vRes = cond->mThenExp->eval( parent, context );
 
 1576     QVariant vElse = mElseExp->
eval( parent, context );
 
 1587   bool foundAnyNonStaticConditions = 
false;
 
 1588   for ( 
WhenThen *cond : std::as_const( mConditions ) )
 
 1590     const bool res = cond->mWhenExp->prepare( parent, context )
 
 1591                      && cond->mThenExp->prepare( parent, context );
 
 1595     foundAnyNonStaticConditions |= !cond->mWhenExp->hasCachedStaticValue();
 
 1596     if ( !foundAnyNonStaticConditions && QgsExpressionUtils::getTVLValue( cond->mWhenExp->cachedStaticValue(), parent ) == QgsExpressionUtils::True )
 
 1600       if ( cond->mThenExp->hasCachedStaticValue() )
 
 1619     const bool res = mElseExp->
prepare( parent, context );
 
 1623     if ( !foundAnyNonStaticConditions )
 
 1647   QString msg( QStringLiteral( 
"CASE" ) );
 
 1648   for ( 
WhenThen *cond : mConditions )
 
 1650     msg += QStringLiteral( 
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
 
 1653     msg += QStringLiteral( 
" ELSE %1" ).arg( mElseExp->
dump() );
 
 1654   msg += QLatin1String( 
" END" );
 
 1661     return QSet< QString >();
 
 1664   for ( 
WhenThen *cond : mConditions )
 
 1666     lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
 
 1678   for ( 
WhenThen *cond : mConditions )
 
 1680     lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
 
 1692   for ( 
WhenThen *cond : mConditions )
 
 1694     lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
 
 1705   QList<const QgsExpressionNode *> lst;
 
 1707   for ( 
WhenThen *cond : mConditions )
 
 1709     lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
 
 1713     lst += mElseExp->
nodes();
 
 1720   for ( 
WhenThen *cond : mConditions )
 
 1722     if ( cond->mWhenExp->needsGeometry() ||
 
 1723          cond->mThenExp->needsGeometry() )
 
 1746     if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
 
 1751     return mElseExp->
isStatic( parent, context );
 
 1759     return QSet< QString >();
 
 1762   const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1764     lst.unite( n->referencedColumns() );
 
 1771   const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1773     lst.unite( n->referencedVariables() );
 
 1780   const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1782     lst.unite( n->referencedFunctions() );
 
 1788   QList<const QgsExpressionNode *> lst;
 
 1790   const QList< QgsExpressionNode * > nodeList = mList->
list();
 
 1801   delete mHigherBound;
 
 1811   bool res = mNode->
prepare( parent, context );
 
 1812   res = res && mLowerBound->
prepare( parent, context );
 
 1813   res = res && mHigherBound->
prepare( parent, context );
 
 1819   const QVariant nodeVal = mNode->
eval( parent, context );
 
 1820   if ( nodeVal.isNull() )
 
 1828   const QVariant lowBoundValue = lowBound.
eval( parent, context );
 
 1829   const bool lowBoundBool { lowBoundValue.toBool() };
 
 1831   if ( ! lowBoundValue.isNull() && ! lowBoundBool )
 
 1833     return QVariant( mNegate );
 
 1837   const QVariant highBoundValue = highBound.
eval( parent, context );
 
 1839   if ( lowBoundValue.isNull() && highBoundValue.isNull() )
 
 1844   const bool highBoundBool { highBoundValue.toBool() };
 
 1847   if ( lowBoundValue.isNull() || highBoundValue.isNull() )
 
 1851     if ( ( lowBoundValue.isNull() && ! highBoundBool ) ||
 
 1852          ( highBoundValue.isNull() && ! lowBoundBool ) )
 
 1854       return QVariant( mNegate );
 
 1862   if ( ! highBoundValue.isNull() && ! highBoundBool )
 
 1864     return QVariant( mNegate );
 
 1867   const bool res { lowBoundBool &&highBoundBool };
 
 1868   return mNegate ? QVariant( ! res ) : QVariant( res );
 
 1874   return QStringLiteral( 
"%1 %2 %3 AND %4" ).arg( mNode->
dump(), mNegate ? QStringLiteral( 
"NOT BETWEEN" ) : QStringLiteral( 
"BETWEEN" ), mLowerBound->
dump(), mHigherBound->
dump() );
 
 1895   return { 
this, mLowerBound, mHigherBound };
 
 1929   if ( !mNode->
isStatic( parent, context ) )
 
 1932   if ( !mLowerBound->
isStatic( parent, context ) )
 
 1935   if ( !mHigherBound->
isStatic( parent, context ) )
 
 1948   return mHigherBound;
 
 1957   : mWhenExp( whenExp )
 
 1958   , mThenExp( thenExp )
 
 1970   return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
 
 1975   return BINARY_OPERATOR_TEXT[mOp];
 
 1982   const QVariant container = mContainer->eval( parent, context );
 
 1984   const QVariant index = mIndex->eval( parent, context );
 
 1987   switch ( container.type() )
 
 1990       return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
 
 1992     case QVariant::List:
 
 1993     case QVariant::StringList:
 
 1995       const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
 
 1996       qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
 
 1997       if ( pos >= list.length() || pos < -list.length() )
 
 2004         pos += list.length();
 
 2007       return list.at( pos );
 
 2011       if ( !container.isNull() )
 
 2024   bool resC = mContainer->prepare( parent, context );
 
 2025   bool resV = mIndex->prepare( parent, context );
 
 2026   return resC && resV;
 
 2031   return QStringLiteral( 
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
 
 2037     return QSet< QString >();
 
 2039   return mContainer->referencedColumns() + mIndex->referencedColumns();
 
 2044   return mContainer->referencedVariables() + mIndex->referencedVariables();
 
 2049   return mContainer->referencedFunctions() + mIndex->referencedFunctions();
 
 2054   QList<const QgsExpressionNode *> lst;
 
 2056   lst += mContainer->nodes() + mIndex->nodes();
 
 2062   return mContainer->needsGeometry() || mIndex->needsGeometry();
 
 2074   return mContainer->isStatic( parent, context ) && mIndex->isStatic( parent, context );