23 #include <QRegularExpression>
25 const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
29 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
30 "+",
"-",
"*",
"/",
"//",
"%",
"^",
34 const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
43 const QList< QgsExpressionNode * > nodeList = mList->
list();
45 needs |= n->needsGeometry();
56 mList.append( node->
node );
57 mNameList.append( cleanNamedNodeName( node->
name ) );
58 mHasNamedNodes =
true;
67 nl->mList.append( node->clone() );
69 nl->mNameList = mNameList;
80 if ( !first ) msg += QLatin1String(
", " );
87 QString QgsExpressionNode::NodeList::cleanNamedNodeName(
const QString &name )
89 QString cleaned = name.toLower();
92 if ( cleaned == QLatin1String(
"geom" ) )
93 cleaned = QStringLiteral(
"geometry" );
94 else if ( cleaned == QLatin1String(
"val" ) )
95 cleaned = QStringLiteral(
"value" );
96 else if ( cleaned == QLatin1String(
"geometry a" ) )
97 cleaned = QStringLiteral(
"geometry1" );
98 else if ( cleaned == QLatin1String(
"geometry b" ) )
99 cleaned = QStringLiteral(
"geometry2" );
109 QVariant val = mOperand->eval( parent, context );
116 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
118 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
122 if ( QgsExpressionUtils::isIntSafe( val ) )
123 return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
124 else if ( QgsExpressionUtils::isDoubleSafe( val ) )
125 return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
139 return mOperand->prepare( parent, context );
145 return QStringLiteral(
"%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
147 return QStringLiteral(
"%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
153 return QSet< QString >();
155 return mOperand->referencedColumns();
160 return mOperand->referencedVariables();
165 return mOperand->referencedFunctions();
170 QList<const QgsExpressionNode *> lst;
172 lst += mOperand->nodes();
178 return mOperand->needsGeometry();
190 return mOperand->isStatic( parent, context );
195 return UNARY_OPERATOR_TEXT[mOp];
202 QVariant vL = mOpLeft->eval( parent, context );
205 if ( mOp == boAnd || mOp == boOr )
207 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
209 if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
211 if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
215 QVariant vR = mOpRight->eval( parent, context );
221 if ( vL.type() == QVariant::String && vR.type() == QVariant::String )
223 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
225 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
227 return QVariant( sL + sR );
236 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
238 else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
241 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
243 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
246 if ( mOp == boMod && iR == 0 )
249 return QVariant( computeInt( iL, iR ) );
251 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
253 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
255 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
257 if ( mOp == boDiv || mOp == boMul || mOp == boMod )
259 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
262 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
264 else if ( mOp == boPlus && ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Time ) ||
265 ( vR.type() == QVariant::Date && vL.type() == QVariant::Time ) ) )
267 QDate date = QgsExpressionUtils::getDateValue( vL.type() == QVariant::Date ? vL : vR, parent );
269 QTime time = QgsExpressionUtils::getTimeValue( vR.type() == QVariant::Time ? vR : vL, parent );
271 QDateTime dt = QDateTime( date, time );
272 return QVariant( dt );
274 else if ( mOp == boMinus && vL.type() == QVariant::Date && vR.type() == QVariant::Date )
276 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
278 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
280 return date1 - date2;
282 else if ( mOp == boMinus && vL.type() == QVariant::Time && vR.type() == QVariant::Time )
284 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
286 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
288 return time1 - time2;
290 else if ( mOp == boMinus && vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime )
292 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
294 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
296 return datetime1 - datetime2;
301 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
303 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
305 if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
307 return QVariant( computeDouble( fL, fR ) );
313 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
315 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
319 return QVariant( qlonglong( std::floor( fL / fR ) ) );
322 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
326 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
328 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
330 return QVariant( std::pow( fL, fR ) );
335 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
337 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
342 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
344 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
353 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
357 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
360 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
364 QVariantList lL = vL.toList();
365 QVariantList lR = vR.toList();
366 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
368 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
371 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
381 return QgsExpressionUtils::isNull( lR.at( i ) );
384 return QgsExpressionUtils::isNull( lL.at( i ) );
394 QVariant eq = eqNode.
eval( parent, context );
396 if ( eq == TVL_False )
400 QVariant v = node.
eval( parent, context );
410 return lL.length() == lR.length();
412 return lL.length() != lR.length();
414 return lL.length() < lR.length();
416 return lL.length() > lR.length();
418 return lL.length() <= lR.length();
420 return lL.length() >= lR.length();
426 else if ( ( vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime ) )
428 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
430 QDateTime dR = QgsExpressionUtils::getDateTimeValue( vR, parent );
437 dL.setTimeSpec( Qt::UTC );
438 dR.setTimeSpec( Qt::UTC );
440 return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
442 else if ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Date ) )
444 const QDate dL = QgsExpressionUtils::getDateValue( vL, parent );
446 const QDate dR = QgsExpressionUtils::getDateValue( vR, parent );
448 return compare( dR.daysTo( dL ) ) ? TVL_True : TVL_False;
450 else if ( ( vL.type() == QVariant::Time && vR.type() == QVariant::Time ) )
452 const QTime dL = QgsExpressionUtils::getTimeValue( vL, parent );
454 const QTime dR = QgsExpressionUtils::getTimeValue( vR, parent );
456 return compare( dR.msecsTo( dL ) ) ? TVL_True : TVL_False;
458 else if ( ( vL.type() != QVariant::String || vR.type() != QVariant::String ) &&
459 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
463 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
465 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
467 return compare( fL - fR ) ? TVL_True : TVL_False;
472 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
474 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
476 return compare( fL - fR ) ? TVL_True : TVL_False;
481 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
483 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
485 int diff = QString::compare( sL, sR );
486 return compare( diff ) ? TVL_True : TVL_False;
491 if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) )
492 return ( mOp == boIs ? TVL_True : TVL_False );
493 else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
494 return ( mOp == boIs ? TVL_False : TVL_True );
498 if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
499 ( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
501 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
503 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
509 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
511 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
513 equal = QString::compare( sL, sR ) == 0;
516 return mOp == boIs ? TVL_True : TVL_False;
518 return mOp == boIs ? TVL_False : TVL_True;
526 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
530 QString str = QgsExpressionUtils::getStringValue( vL, parent );
532 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
536 if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike )
538 QString esc_regexp = QRegExp::escape( regexp );
540 if ( esc_regexp.startsWith(
'%' ) )
542 esc_regexp.replace( 0, 1, QStringLiteral(
".*" ) );
544 thread_local QRegExp rx1( QStringLiteral(
"[^\\\\](%)" ) );
546 while ( ( pos = rx1.indexIn( esc_regexp, pos ) ) != -1 )
548 esc_regexp.replace( pos + 1, 1, QStringLiteral(
".*" ) );
551 thread_local QRegExp rx2( QStringLiteral(
"\\\\%" ) );
552 esc_regexp.replace( rx2, QStringLiteral(
"%" ) );
553 if ( esc_regexp.startsWith(
'_' ) )
555 esc_regexp.replace( 0, 1, QStringLiteral(
"." ) );
557 thread_local QRegExp rx3( QStringLiteral(
"[^\\\\](_)" ) );
559 while ( ( pos = rx3.indexIn( esc_regexp, pos ) ) != -1 )
561 esc_regexp.replace( pos + 1, 1,
'.' );
564 esc_regexp.replace( QLatin1String(
"\\\\_" ), QLatin1String(
"_" ) );
566 matches = QRegExp( esc_regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
570 matches = QRegularExpression( regexp ).match( str ).hasMatch();
573 if ( mOp == boNotLike || mOp == boNotILike )
578 return matches ? TVL_True : TVL_False;
582 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
586 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
588 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
590 return QVariant( sL + sR );
597 bool QgsExpressionNodeBinaryOperator::compare(
double diff )
619 qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
639 QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d,
QgsInterval *i )
644 return d.addSecs( i->
seconds() );
646 return d.addSecs( -i->
seconds() );
653 double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
666 return std::fmod( x, y );
680 bool resL = mOpLeft->prepare( parent, context );
681 bool resR = mOpRight->prepare( parent, context );
727 Q_ASSERT(
false &&
"unexpected binary operator" );
763 Q_ASSERT(
false &&
"unexpected binary operator" );
773 QString rdump( mOpRight->dump() );
778 rdump.prepend(
'(' ).append(
')' );
782 if ( leftAssociative() )
784 fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
785 fmt += QLatin1String(
" %2 " );
786 fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
790 fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
791 fmt += QLatin1String(
" %2 " );
792 fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
795 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
801 return QSet< QString >();
803 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
808 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
813 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
818 QList<const QgsExpressionNode *> lst;
820 lst += mOpLeft->nodes() + mOpRight->nodes();
826 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
838 return mOpLeft->isStatic( parent, context ) && mOpRight->isStatic( parent, context );
845 if ( mList->count() == 0 )
846 return mNotIn ? TVL_True : TVL_False;
847 QVariant v1 = mNode->eval( parent, context );
849 if ( QgsExpressionUtils::isNull( v1 ) )
852 bool listHasNull =
false;
854 const QList< QgsExpressionNode * > nodeList = mList->list();
857 QVariant v2 = n->eval( parent, context );
859 if ( QgsExpressionUtils::isNull( v2 ) )
865 if ( ( v1.type() != QVariant::String || v2.type() != QVariant::String ) &&
866 QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
870 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
872 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
878 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
880 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
882 equal = QString::compare( s1, s2 ) == 0;
886 return mNotIn ? TVL_False : TVL_True;
894 return mNotIn ? TVL_True : TVL_False;
910 bool res = mNode->prepare( parent, context );
911 const QList< QgsExpressionNode * > nodeList = mList->list();
914 res = res && n->prepare( parent, context );
921 return QStringLiteral(
"%1 %2 IN (%3)" ).arg( mNode->dump(), mNotIn ?
"NOT" :
"", mList->dump() );
933 if ( !mNode->isStatic( parent, context ) )
936 const QList< QgsExpressionNode * > nodeList = mList->list();
939 if ( !n->isStatic( parent, context ) )
950 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
953 QVariant res = fd->
run( mArgs, context, parent,
this );
961 : mFnIndex( fnIndex )
964 if ( !
args || functionParams.isEmpty() )
975 while ( idx < args->names().size() &&
args->
names().at( idx ).isEmpty() )
982 for ( ; idx < functionParams.count(); ++idx )
984 int nodeIdx =
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
1014 bool res = fd->
prepare(
this, parent, context );
1017 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1020 res = res && n->prepare( parent, context );
1030 return QStringLiteral(
"%1%2" ).arg( fd->
name(), fd->
name().startsWith(
'$' ) ? QString() : QStringLiteral(
"()" ) );
1032 return QStringLiteral(
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->
dump() : QString() );
1038 return QSet< QString >();
1046 return functionColumns;
1050 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1053 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
1054 functionColumns.unite( n->referencedColumns() );
1058 return functionColumns;
1064 if ( fd->
name() == QLatin1String(
"var" ) )
1066 if ( !mArgs->
list().isEmpty() )
1070 return QSet<QString>() << var->
value().toString();
1072 return QSet<QString>() << QString();
1076 QSet<QString> functionVariables = QSet<QString>();
1079 return functionVariables;
1081 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1084 functionVariables.unite( n->referencedVariables() );
1087 return functionVariables;
1094 QSet<QString> functions = QSet<QString>();
1095 functions.insert( fd->
name() );
1100 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1103 functions.unite( n->referencedFunctions() );
1110 QList<const QgsExpressionNode *> lst;
1115 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1125 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1128 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1130 needs |= n->needsGeometry();
1153 if ( functionParams.isEmpty() )
1160 QSet< int > providedArgs;
1161 QSet< int > handledArgs;
1164 while (
args->
names().at( idx ).isEmpty() )
1166 providedArgs << idx;
1172 for ( ; idx < functionParams.count(); ++idx )
1174 int nodeIdx =
args->
names().indexOf( functionParams.at( idx ).name().toLower() );
1177 if ( !functionParams.at( idx ).optional() )
1179 error = QStringLiteral(
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1185 if ( providedArgs.contains( idx ) )
1187 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1191 providedArgs << idx;
1192 handledArgs << nodeIdx;
1197 const QStringList nameList =
args->
names();
1198 for (
const QString &name : nameList )
1200 if ( !name.isEmpty() && !functionParams.contains( name ) )
1205 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1207 int functionIdx = functionParams.indexOf( name );
1208 if ( providedArgs.contains( functionIdx ) )
1210 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1245 if ( mValue.isNull() )
1246 return QStringLiteral(
"NULL" );
1248 switch ( mValue.type() )
1251 return QString::number( mValue.toInt() );
1252 case QVariant::Double:
1253 return QString::number( mValue.toDouble() );
1254 case QVariant::LongLong:
1255 return QString::number( mValue.toLongLong() );
1256 case QVariant::String:
1258 case QVariant::Bool:
1259 return mValue.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
1261 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1267 return QSet<QString>();
1272 return QSet<QString>();
1277 return QSet<QString>();
1282 QList<const QgsExpressionNode *> lst;
1335 parent->
setEvalErrorString( tr(
"No feature available for field '%1' evaluation" ).arg( mName ) );
1372 const thread_local QRegExp re( QStringLiteral(
"^[A-Za-z_\x80-\xff][A-Za-z0-9_\x80-\xff]*$" ) );
1378 return QSet<QString>() << mName;
1383 return QSet<QString>();
1388 return QSet<QString>();
1393 QList<const QgsExpressionNode *> result;
1420 : mConditions( *conditions )
1421 , mElseExp( elseExp )
1429 qDeleteAll( mConditions );
1439 for (
WhenThen *cond : qgis::as_const( mConditions ) )
1441 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1442 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1444 if ( tvl == QgsExpressionUtils::True )
1446 QVariant vRes = cond->mThenExp->eval( parent, context );
1454 QVariant vElse = mElseExp->
eval( parent, context );
1466 for (
WhenThen *cond : qgis::as_const( mConditions ) )
1468 res = cond->mWhenExp->prepare( parent, context )
1469 & cond->mThenExp->prepare( parent, context );
1475 return mElseExp->
prepare( parent, context );
1482 QString msg( QStringLiteral(
"CASE" ) );
1483 for (
WhenThen *cond : mConditions )
1485 msg += QStringLiteral(
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1488 msg += QStringLiteral(
" ELSE %1" ).arg( mElseExp->
dump() );
1489 msg += QLatin1String(
" END" );
1496 return QSet< QString >();
1499 for (
WhenThen *cond : mConditions )
1501 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1513 for (
WhenThen *cond : mConditions )
1515 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1527 for (
WhenThen *cond : mConditions )
1529 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1540 QList<const QgsExpressionNode *> lst;
1542 for (
WhenThen *cond : mConditions )
1544 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1548 lst += mElseExp->
nodes();
1555 for (
WhenThen *cond : mConditions )
1557 if ( cond->mWhenExp->needsGeometry() ||
1558 cond->mThenExp->needsGeometry() )
1581 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1586 return mElseExp->
isStatic( parent, context );
1594 return QSet< QString >();
1597 const QList< QgsExpressionNode * > nodeList = mList->
list();
1599 lst.unite( n->referencedColumns() );
1606 const QList< QgsExpressionNode * > nodeList = mList->
list();
1608 lst.unite( n->referencedVariables() );
1615 const QList< QgsExpressionNode * > nodeList = mList->
list();
1617 lst.unite( n->referencedFunctions() );
1623 QList<const QgsExpressionNode *> lst;
1625 const QList< QgsExpressionNode * > nodeList = mList->
list();
1632 : mWhenExp( whenExp )
1633 , mThenExp( thenExp )
1645 return new WhenThen( mWhenExp->clone(), mThenExp->clone() );
1650 return BINARY_OPERATOR_TEXT[mOp];
1657 const QVariant container = mContainer->eval( parent, context );
1659 const QVariant index = mIndex->eval( parent, context );
1662 switch ( container.type() )
1665 return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
1667 case QVariant::List:
1668 case QVariant::StringList:
1670 const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
1671 qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
1672 if ( pos >= list.length() || pos < -list.length() )
1679 pos += list.length();
1682 return list.at( pos );
1698 bool resC = mContainer->prepare( parent, context );
1699 bool resV = mIndex->prepare( parent, context );
1700 return resC && resV;
1705 return QStringLiteral(
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
1711 return QSet< QString >();
1713 return mContainer->referencedColumns() + mIndex->referencedColumns();
1718 return mContainer->referencedVariables() + mIndex->referencedVariables();
1723 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
1728 QList<const QgsExpressionNode *> lst;
1730 lst += mContainer->nodes() + mIndex->nodes();
1736 return mContainer->needsGeometry() || mIndex->needsGeometry();
1748 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.
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.
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.
QgsExpressionNodeColumnRef(const QString &name)
Constructor for QgsExpressionNodeColumnRef, referencing the column with the specified name.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
QString dump() const override
Dump this node into a serialized (part) of an expression.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
Represents a "WHEN... THEN..." portation of a CASE WHEN clause in an expression.
WhenThen(QgsExpressionNode *whenExp, QgsExpressionNode *thenExp)
A combination of when and then.
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.
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.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QgsExpressionNode * clone() const override
Generate a clone of this node.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression.
QVariant value() const
The value of the literal.
QgsExpressionNodeLiteral(const QVariant &value)
Constructor for QgsExpressionNodeLiteral, with the specified literal value.
A unary node is either negative as in boolean (not) or as in numbers (minus).
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
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.
virtual QList< const QgsExpressionNode * > nodes() const =0
Returns a list of all nodes which are used in this 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 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.
NodeType
Known node types.
@ ntIndexOperator
Index operator.
virtual bool needsGeometry() const =0
Abstract virtual method which returns if the geometry is required to evaluate 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.
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
virtual QgsExpressionNode * clone() const =0
Generate a clone of this node.
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)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
bool isValid() const
Returns the validity of this feature.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Container of fields for a vector layer.
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.
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.