23 const char *QgsExpressionNodeBinaryOperator::BINARY_OPERATOR_TEXT[] =
27 "=",
"<>",
"<=",
">=",
"<",
">",
"~",
"LIKE",
"NOT LIKE",
"ILIKE",
"NOT ILIKE",
"IS",
"IS NOT",
28 "+",
"-",
"*",
"/",
"//",
"%",
"^",
32 const char *QgsExpressionNodeUnaryOperator::UNARY_OPERATOR_TEXT[] =
41 const QList< QgsExpressionNode * > nodeList = mList->
list();
43 needs |= n->needsGeometry();
55 mNameList.append( node->
name.toLower() );
56 mHasNamedNodes =
true;
67 nl->mNameList = mNameList;
78 if ( !first ) msg += QLatin1String(
", " );
90 QVariant val = mOperand->eval( parent, context );
97 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( val, parent );
99 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::NOT[tvl] );
103 if ( QgsExpressionUtils::isIntSafe( val ) )
104 return QVariant( - QgsExpressionUtils::getIntValue( val, parent ) );
105 else if ( QgsExpressionUtils::isDoubleSafe( val ) )
106 return QVariant( - QgsExpressionUtils::getDoubleValue( val, parent ) );
110 Q_ASSERT(
false &&
"unknown unary operation" );
122 return mOperand->prepare( parent, context );
127 if ( dynamic_cast<QgsExpressionNodeBinaryOperator *>( mOperand ) )
128 return QStringLiteral(
"%1 ( %2 )" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
130 return QStringLiteral(
"%1 %2" ).arg( UNARY_OPERATOR_TEXT[mOp], mOperand->dump() );
135 return mOperand->referencedColumns();
140 return mOperand->referencedVariables();
145 return mOperand->referencedFunctions();
150 QList<const QgsExpressionNode *> lst;
152 lst += mOperand->nodes();
158 return mOperand->needsGeometry();
170 return mOperand->isStatic( parent, context );
175 return UNARY_OPERATOR_TEXT[mOp];
182 QVariant vL = mOpLeft->eval( parent, context );
185 if ( mOp == boAnd || mOp == boOr )
187 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent );
189 if ( mOp == boAnd && tvlL == QgsExpressionUtils::False )
191 if ( mOp == boOr && tvlL == QgsExpressionUtils::True )
195 QVariant vR = mOpRight->eval( parent, context );
201 if ( vL.type() == QVariant::String && vR.type() == QVariant::String )
203 QString sL = QgsExpressionUtils::isNull( vL ) ? QString() : QgsExpressionUtils::getStringValue( vL, parent );
205 QString sR = QgsExpressionUtils::isNull( vR ) ? QString() : QgsExpressionUtils::getStringValue( vR, parent );
207 return QVariant( sL + sR );
216 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
218 else if ( mOp != boDiv && QgsExpressionUtils::isIntSafe( vL ) && QgsExpressionUtils::isIntSafe( vR ) )
221 qlonglong iL = QgsExpressionUtils::getIntValue( vL, parent );
223 qlonglong iR = QgsExpressionUtils::getIntValue( vR, parent );
226 if ( mOp == boMod && iR == 0 )
229 return QVariant( computeInt( iL, iR ) );
231 else if ( QgsExpressionUtils::isDateTimeSafe( vL ) && QgsExpressionUtils::isIntervalSafe( vR ) )
233 QDateTime dL = QgsExpressionUtils::getDateTimeValue( vL, parent );
235 QgsInterval iL = QgsExpressionUtils::getInterval( vR, parent );
237 if ( mOp == boDiv || mOp == boMul || mOp == boMod )
239 parent->
setEvalErrorString( tr(
"Can't perform /, *, or % on DateTime and Interval" ) );
242 return QVariant( computeDateTimeFromInterval( dL, &iL ) );
244 else if ( mOp == boPlus && ( ( vL.type() == QVariant::Date && vR.type() == QVariant::Time ) ||
245 ( vR.type() == QVariant::Date && vL.type() == QVariant::Time ) ) )
247 QDate date = QgsExpressionUtils::getDateValue( vL.type() == QVariant::Date ? vL : vR, parent );
249 QTime time = QgsExpressionUtils::getTimeValue( vR.type() == QVariant::Time ? vR : vL, parent );
251 QDateTime dt = QDateTime( date, time );
252 return QVariant( dt );
254 else if ( mOp == boMinus && vL.type() == QVariant::Date && vR.type() == QVariant::Date )
256 QDate date1 = QgsExpressionUtils::getDateValue( vL, parent );
258 QDate date2 = QgsExpressionUtils::getDateValue( vR, parent );
260 return date1 - date2;
262 else if ( mOp == boMinus && vL.type() == QVariant::Time && vR.type() == QVariant::Time )
264 QTime time1 = QgsExpressionUtils::getTimeValue( vL, parent );
266 QTime time2 = QgsExpressionUtils::getTimeValue( vR, parent );
268 return time1 - time2;
270 else if ( mOp == boMinus && vL.type() == QVariant::DateTime && vR.type() == QVariant::DateTime )
272 QDateTime datetime1 = QgsExpressionUtils::getDateTimeValue( vL, parent );
274 QDateTime datetime2 = QgsExpressionUtils::getDateTimeValue( vR, parent );
276 return datetime1 - datetime2;
281 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
283 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
285 if ( ( mOp == boDiv || mOp == boMod ) && fR == 0. )
287 return QVariant( computeDouble( fL, fR ) );
293 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
295 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
299 return QVariant( qlonglong( std::floor( fL / fR ) ) );
302 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
306 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
308 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
310 return QVariant( std::pow( fL, fR ) );
315 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
317 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::AND[tvlL][tvlR] );
322 QgsExpressionUtils::TVL tvlL = QgsExpressionUtils::getTVLValue( vL, parent ), tvlR = QgsExpressionUtils::getTVLValue( vR, parent );
324 return QgsExpressionUtils::tvl2variant( QgsExpressionUtils::OR[tvlL][tvlR] );
333 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
337 else if ( QgsExpressionUtils::isList( vL ) || QgsExpressionUtils::isList( vR ) )
340 if ( !QgsExpressionUtils::isList( vL ) || !QgsExpressionUtils::isList( vR ) )
344 QVariantList lL = vL.toList();
345 QVariantList lR = vR.toList();
346 for (
int i = 0; i < lL.length() && i < lR.length(); i++ )
348 if ( QgsExpressionUtils::isNull( lL.at( i ) ) && QgsExpressionUtils::isNull( lR.at( i ) ) )
351 if ( QgsExpressionUtils::isNull( lL.at( i ) ) || QgsExpressionUtils::isNull( lR.at( i ) ) )
361 return QgsExpressionUtils::isNull( lR.at( i ) );
364 return QgsExpressionUtils::isNull( lL.at( i ) );
374 QVariant eq = eqNode.
eval( parent, context );
376 if ( eq == TVL_False )
380 QVariant v =
node.
eval( parent, context );
390 return lL.length() == lR.length();
392 return lL.length() != lR.length();
394 return lL.length() < lR.length();
396 return lL.length() > lR.length();
398 return lL.length() <= lR.length();
400 return lL.length() >= lR.length();
406 else if ( ( vL.type() != QVariant::String || vR.type() != QVariant::String ) &&
407 QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) )
411 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
413 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
415 return compare( fL - fR ) ? TVL_True : TVL_False;
420 double fL = QgsExpressionUtils::getInterval( vL, parent ).seconds();
422 double fR = QgsExpressionUtils::getInterval( vR, parent ).seconds();
424 return compare( fL - fR ) ? TVL_True : TVL_False;
429 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
431 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
433 int diff = QString::compare( sL, sR );
434 return compare( diff ) ? TVL_True : TVL_False;
439 if ( QgsExpressionUtils::isNull( vL ) && QgsExpressionUtils::isNull( vR ) )
440 return ( mOp == boIs ? TVL_True : TVL_False );
441 else if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
442 return ( mOp == boIs ? TVL_False : TVL_True );
446 if ( QgsExpressionUtils::isDoubleSafe( vL ) && QgsExpressionUtils::isDoubleSafe( vR ) &&
447 ( vL.type() != QVariant::String || vR.type() != QVariant::String ) )
449 double fL = QgsExpressionUtils::getDoubleValue( vL, parent );
451 double fR = QgsExpressionUtils::getDoubleValue( vR, parent );
457 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
459 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
461 equal = QString::compare( sL, sR ) == 0;
464 return mOp == boIs ? TVL_True : TVL_False;
466 return mOp == boIs ? TVL_False : TVL_True;
474 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
478 QString str = QgsExpressionUtils::getStringValue( vL, parent );
480 QString regexp = QgsExpressionUtils::getStringValue( vR, parent );
484 if ( mOp == boLike || mOp == boILike || mOp == boNotLike || mOp == boNotILike )
486 QString esc_regexp = QRegExp::escape( regexp );
488 if ( esc_regexp.startsWith(
'%' ) )
490 esc_regexp.replace( 0, 1, QStringLiteral(
".*" ) );
492 QRegExp rx(
"[^\\\\](%)" );
494 while ( ( pos = rx.indexIn( esc_regexp, pos ) ) != -1 )
496 esc_regexp.replace( pos + 1, 1, QStringLiteral(
".*" ) );
499 rx.setPattern( QStringLiteral(
"\\\\%" ) );
500 esc_regexp.replace( rx, QStringLiteral(
"%" ) );
501 if ( esc_regexp.startsWith(
'_' ) )
503 esc_regexp.replace( 0, 1, QStringLiteral(
"." ) );
505 rx.setPattern( QStringLiteral(
"[^\\\\](_)" ) );
507 while ( ( pos = rx.indexIn( esc_regexp, pos ) ) != -1 )
509 esc_regexp.replace( pos + 1, 1,
'.' );
512 rx.setPattern( QStringLiteral(
"\\\\_" ) );
513 esc_regexp.replace( rx, QStringLiteral(
"_" ) );
514 matches = QRegExp( esc_regexp, mOp == boLike || mOp == boNotLike ? Qt::CaseSensitive : Qt::CaseInsensitive ).exactMatch( str );
518 matches = QRegExp( regexp ).indexIn( str ) != -1;
521 if ( mOp == boNotLike || mOp == boNotILike )
526 return matches ? TVL_True : TVL_False;
530 if ( QgsExpressionUtils::isNull( vL ) || QgsExpressionUtils::isNull( vR ) )
534 QString sL = QgsExpressionUtils::getStringValue( vL, parent );
536 QString sR = QgsExpressionUtils::getStringValue( vR, parent );
538 return QVariant( sL + sR );
548 bool QgsExpressionNodeBinaryOperator::compare(
double diff )
570 qlonglong QgsExpressionNodeBinaryOperator::computeInt( qlonglong x, qlonglong y )
590 QDateTime QgsExpressionNodeBinaryOperator::computeDateTimeFromInterval(
const QDateTime &d,
QgsInterval *i )
595 return d.addSecs( i->
seconds() );
597 return d.addSecs( -i->
seconds() );
604 double QgsExpressionNodeBinaryOperator::computeDouble(
double x,
double y )
617 return std::fmod( x, y );
631 bool resL = mOpLeft->prepare( parent, context );
632 bool resR = mOpRight->prepare( parent, context );
678 Q_ASSERT(
false &&
"unexpected binary operator" );
714 Q_ASSERT(
false &&
"unexpected binary operator" );
724 QString rdump( mOpRight->dump() );
729 rdump.prepend(
'(' ).append(
')' );
733 if ( leftAssociative() )
735 fmt += lOp && ( lOp->
precedence() < precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
736 fmt += QLatin1String(
" %2 " );
737 fmt += rOp && ( rOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
741 fmt += lOp && ( lOp->
precedence() <= precedence() ) ? QStringLiteral(
"(%1)" ) : QStringLiteral(
"%1" );
742 fmt += QLatin1String(
" %2 " );
743 fmt += rOp && ( rOp->
precedence() < precedence() ) ? QStringLiteral(
"(%3)" ) : QStringLiteral(
"%3" );
746 return fmt.arg( mOpLeft->dump(), BINARY_OPERATOR_TEXT[mOp], rdump );
751 return mOpLeft->referencedColumns() + mOpRight->referencedColumns();
756 return mOpLeft->referencedVariables() + mOpRight->referencedVariables();
761 return mOpLeft->referencedFunctions() + mOpRight->referencedFunctions();
766 QList<const QgsExpressionNode *> lst;
768 lst += mOpLeft->nodes() + mOpRight->nodes();
774 return mOpLeft->needsGeometry() || mOpRight->needsGeometry();
786 return mOpLeft->isStatic( parent, context ) && mOpRight->isStatic( parent, context );
793 if ( mList->
count() == 0 )
794 return mNotIn ? TVL_True : TVL_False;
795 QVariant v1 = mNode->
eval( parent, context );
797 if ( QgsExpressionUtils::isNull( v1 ) )
800 bool listHasNull =
false;
802 const QList< QgsExpressionNode * > nodeList = mList->
list();
805 QVariant v2 = n->eval( parent, context );
807 if ( QgsExpressionUtils::isNull( v2 ) )
813 if ( ( v1.type() != QVariant::String || v2.type() != QVariant::String ) &&
814 QgsExpressionUtils::isDoubleSafe( v1 ) && QgsExpressionUtils::isDoubleSafe( v2 ) )
818 double f1 = QgsExpressionUtils::getDoubleValue( v1, parent );
820 double f2 = QgsExpressionUtils::getDoubleValue( v2, parent );
826 QString s1 = QgsExpressionUtils::getStringValue( v1, parent );
828 QString s2 = QgsExpressionUtils::getStringValue( v2, parent );
830 equal = QString::compare( s1, s2 ) == 0;
834 return mNotIn ? TVL_False : TVL_True;
842 return mNotIn ? TVL_True : TVL_False;
858 bool res = mNode->
prepare( parent, context );
859 const QList< QgsExpressionNode * > nodeList = mList->
list();
862 res = res && n->prepare( parent, context );
869 return QStringLiteral(
"%1 %2 IN (%3)" ).arg( mNode->
dump(), mNotIn ?
"NOT" :
"", mList->
dump() );
881 if ( !mNode->
isStatic( parent, context ) )
884 const QList< QgsExpressionNode * > nodeList = mList->
list();
887 if ( !n->isStatic( parent, context ) )
898 QString name = QgsExpression::QgsExpression::Functions()[mFnIndex]->name();
901 QVariant res = fd->
run( mArgs, context, parent,
this );
909 : mFnIndex( fnIndex )
912 if ( !args || functionParams.isEmpty() )
923 while ( idx < args->names().size() && args->
names().at( idx ).isEmpty() )
925 mArgs->
append( args->
list().at( idx )->clone() );
930 for ( ; idx < functionParams.count(); ++idx )
932 int nodeIdx = args->
names().indexOf( functionParams.at( idx ).name().toLower() );
940 mArgs->
append( args->
list().at( nodeIdx )->clone() );
962 bool res = fd->
prepare(
this, parent, context );
965 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
968 res = res && n->prepare( parent, context );
978 return QStringLiteral(
"%1%2" ).arg( fd->
name(), fd->
name().startsWith(
'$' ) ?
"" :
"()" );
980 return QStringLiteral(
"%1(%2)" ).arg( fd->
name(), mArgs ? mArgs->
dump() : QString() );
991 return functionColumns;
995 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
998 if ( fd->
parameters().count() <= paramIndex || !fd->
parameters().at( paramIndex ).isSubExpression() )
999 functionColumns.unite( n->referencedColumns() );
1003 return functionColumns;
1009 if ( fd->
name() == QLatin1String(
"var" ) )
1011 if ( !mArgs->
list().isEmpty() )
1015 return QSet<QString>() << var->
value().toString();
1017 return QSet<QString>() << QString();
1021 QSet<QString> functionVariables = QSet<QString>();
1024 return functionVariables;
1026 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1029 functionVariables.unite( n->referencedVariables() );
1032 return functionVariables;
1039 QSet<QString> functions = QSet<QString>();
1040 functions.insert( fd->
name() );
1045 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1048 functions.unite( n->referencedFunctions() );
1055 QList<const QgsExpressionNode *> lst;
1060 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1070 bool needs = QgsExpression::QgsExpression::Functions()[mFnIndex]->usesGeometry(
this );
1073 const QList< QgsExpressionNode * > nodeList = mArgs->
list();
1075 needs |= n->needsGeometry();
1098 if ( functionParams.isEmpty() )
1100 error = QStringLiteral(
"%1 does not support named QgsExpressionFunction::Parameters" ).arg(
QgsExpression::Functions()[fnIndex]->name() );
1105 QSet< int > providedArgs;
1106 QSet< int > handledArgs;
1109 while ( args->
names().at( idx ).isEmpty() )
1111 providedArgs << idx;
1117 for ( ; idx < functionParams.count(); ++idx )
1119 int nodeIdx = args->
names().indexOf( functionParams.at( idx ).name().toLower() );
1122 if ( !functionParams.at( idx ).optional() )
1124 error = QStringLiteral(
"No value specified for QgsExpressionFunction::Parameter '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1130 if ( providedArgs.contains( idx ) )
1132 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( idx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1136 providedArgs << idx;
1137 handledArgs << nodeIdx;
1142 const QStringList nameList = args->
names();
1143 for (
const QString &name : nameList )
1145 if ( !name.isEmpty() && !functionParams.contains( name ) )
1147 error = QStringLiteral(
"Invalid QgsExpressionFunction::Parameter name '%1' for %2" ).arg( name,
QgsExpression::Functions()[fnIndex]->name() );
1150 if ( !name.isEmpty() && !handledArgs.contains( idx ) )
1152 int functionIdx = functionParams.indexOf( name );
1153 if ( providedArgs.contains( functionIdx ) )
1155 error = QStringLiteral(
"Duplicate QgsExpressionFunction::Parameter specified for '%1' for %2" ).arg( functionParams.at( functionIdx ).name(),
QgsExpression::Functions()[
fnIndex]->name() );
1190 if ( mValue.isNull() )
1191 return QStringLiteral(
"NULL" );
1193 switch ( mValue.type() )
1196 return QString::number( mValue.toInt() );
1197 case QVariant::Double:
1198 return QString::number( mValue.toDouble() );
1199 case QVariant::LongLong:
1200 return QString::number( mValue.toLongLong() );
1201 case QVariant::String:
1203 case QVariant::Bool:
1204 return mValue.toBool() ? QStringLiteral(
"TRUE" ) : QStringLiteral(
"FALSE" );
1206 return tr(
"[unsupported type: %1; value: %2]" ).arg( mValue.typeName(), mValue.toString() );
1212 return QSet<QString>();
1217 return QSet<QString>();
1222 return QSet<QString>();
1227 QList<const QgsExpressionNode *> lst;
1279 parent->
setEvalErrorString( QStringLiteral(
"Column '%1' not found" ).arg( mName ) );
1317 return QSet<QString>() << mName;
1322 return QSet<QString>();
1327 return QSet<QString>();
1332 QList<const QgsExpressionNode *> result;
1359 : mConditions( *conditions )
1360 , mElseExp( elseExp )
1368 qDeleteAll( mConditions );
1378 for (
WhenThen *cond : qgis::as_const( mConditions ) )
1380 QVariant vWhen = cond->mWhenExp->eval( parent, context );
1381 QgsExpressionUtils::TVL tvl = QgsExpressionUtils::getTVLValue( vWhen, parent );
1383 if ( tvl == QgsExpressionUtils::True )
1385 QVariant vRes = cond->mThenExp->eval( parent, context );
1393 QVariant vElse = mElseExp->
eval( parent, context );
1405 for (
WhenThen *cond : qgis::as_const( mConditions ) )
1407 res = cond->mWhenExp->prepare( parent, context )
1408 & cond->mThenExp->prepare( parent, context );
1414 return mElseExp->
prepare( parent, context );
1421 QString msg( QStringLiteral(
"CASE" ) );
1422 for (
WhenThen *cond : mConditions )
1424 msg += QStringLiteral(
" WHEN %1 THEN %2" ).arg( cond->mWhenExp->dump(), cond->mThenExp->dump() );
1427 msg += QStringLiteral(
" ELSE %1" ).arg( mElseExp->
dump() );
1428 msg += QStringLiteral(
" END" );
1435 for (
WhenThen *cond : mConditions )
1437 lst += cond->mWhenExp->referencedColumns() + cond->mThenExp->referencedColumns();
1449 for (
WhenThen *cond : mConditions )
1451 lst += cond->mWhenExp->referencedVariables() + cond->mThenExp->referencedVariables();
1463 for (
WhenThen *cond : mConditions )
1465 lst += cond->mWhenExp->referencedFunctions() + cond->mThenExp->referencedFunctions();
1476 QList<const QgsExpressionNode *> lst;
1478 for (
WhenThen *cond : mConditions )
1480 lst += cond->mWhenExp->nodes() + cond->mThenExp->nodes();
1484 lst += mElseExp->
nodes();
1491 for (
WhenThen *cond : mConditions )
1493 if ( cond->mWhenExp->needsGeometry() ||
1494 cond->mThenExp->needsGeometry() )
1505 conditions.append( wt->clone() );
1516 if ( !wt->mWhenExp->isStatic( parent, context ) || !wt->mThenExp->isStatic( parent, context ) )
1521 return mElseExp->
isStatic( parent, context );
1528 QSet<QString> lst( mNode->referencedColumns() );
1529 const QList< QgsExpressionNode * > nodeList = mList->list();
1531 lst.unite( n->referencedColumns() );
1537 QSet<QString> lst( mNode->referencedVariables() );
1538 const QList< QgsExpressionNode * > nodeList = mList->list();
1540 lst.unite( n->referencedVariables() );
1546 QSet<QString> lst( mNode->referencedFunctions() );
1547 const QList< QgsExpressionNode * > nodeList = mList->list();
1549 lst.unite( n->referencedFunctions() );
1555 QList<const QgsExpressionNode *> lst;
1557 const QList< QgsExpressionNode * > nodeList = mList->list();
1564 : mWhenExp( whenExp )
1565 , mThenExp( thenExp )
1582 return BINARY_OPERATOR_TEXT[mOp];
1589 const QVariant container = mContainer->eval( parent, context );
1591 const QVariant index = mIndex->eval( parent, context );
1594 switch ( container.type() )
1597 return QgsExpressionUtils::getMapValue( container, parent ).value( index.toString() );
1599 case QVariant::List:
1600 case QVariant::StringList:
1602 const QVariantList list = QgsExpressionUtils::getListValue( container, parent );
1603 qlonglong pos = QgsExpressionUtils::getIntValue( index, parent );
1604 if ( pos >= list.length() || pos < -list.length() )
1611 pos += list.length();
1614 return list.at( pos );
1630 bool resC = mContainer->prepare( parent, context );
1631 bool resV = mIndex->prepare( parent, context );
1632 return resC && resV;
1637 return QStringLiteral(
"%1[%2]" ).arg( mContainer->dump(), mIndex->dump() );
1642 return mContainer->referencedColumns() + mIndex->referencedColumns();
1647 return mContainer->referencedVariables() + mIndex->referencedVariables();
1652 return mContainer->referencedFunctions() + mIndex->referencedFunctions();
1657 QList<const QgsExpressionNode *> lst;
1659 lst += mContainer->nodes() + mIndex->nodes();
1665 return mContainer->needsGeometry() || mIndex->needsGeometry();
1677 return mContainer->isStatic( parent, context ) && mIndex->isStatic( parent, context );
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
void cloneTo(QgsExpressionNode *target) const
Copies the members of this node to the node provided in target.
bool isValid() const
Returns the validity of this feature.
Class for parsing and evaluation of expressions (formerly called "search strings").
QStringList names() const
Returns a list of names for nodes.
QgsExpressionNode * node
Node.
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...
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 prepare(QgsExpression *parent, const QgsExpressionContext *context)
Prepare this node for evaluation.
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...
virtual QString dump() const =0
Dump this node into a serialized (part) of an expression.
QgsExpressionNode::NodeList * args() const
Returns a list of arguments specified for the function.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes 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.
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...
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
QgsExpressionNodeCondition(QgsExpressionNodeCondition::WhenThenList *conditions, QgsExpressionNode *elseExp=nullptr)
Create a new node with the given list of conditions and an optional elseExp expression.
int params() const
The number of parameters this function takes.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
int precedence() const
Returns the precedence index for the operator.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool hasFunction(const QString &name) const
Checks whether a specified function is contained in the context.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
WhenThenList conditions() const
The list of WHEN THEN expression parts of the expression.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
NodeType
Known node types.
QgsExpressionNodeInOperator(QgsExpressionNode *node, QgsExpressionNode::NodeList *list, bool notin=false)
This node tests if the result of node is in the result of list.
An expression node for CASE WHEN clauses.
double seconds() const
Returns the interval duration in seconds.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
virtual QSet< QString > referencedColumns(const QgsExpressionNodeFunction *node) const
Returns a set of field names which are required for this function.
Container of fields for a vector layer.
~QgsExpressionNodeInOperator() override
bool hasVariable(const QString &name) const
Check whether a variable is specified by any scope within the context.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
virtual QgsExpressionNode * clone() const =0
Generate a clone of this node.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QSet< QString > referencedVariables() const override
Returns a set of all variables 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...
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QList< QgsExpressionFunction::Parameter > ParameterList
List of parameters, used for function definition.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QVariant variable(const QString &name) const
Fetches a matching variable from the context.
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.
void setEvalErrorString(const QString &str)
Sets evaluation error (used internally by evaluation functions)
bool hasFeature() const
Returns true if the context has a feature associated with it.
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.
QgsExpressionNode * clone() const override
Generate a clone of this node.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
#define ENSURE_NO_EVAL_ERROR
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QString text() const
Returns a the name of this operator without the operands.
#define SET_EVAL_ERROR(x)
virtual QSet< QString > referencedColumns() const =0
Abstract virtual method which returns a list of columns required to evaluate this node...
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
virtual QSet< QString > referencedVariables() const =0
Returns a set of all variables which are used in this expression.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
const QgsExpressionFunction::ParameterList & parameters() const
Returns the list of named parameters for the function, if set.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
~QgsExpressionNodeFunction() override
An expression node for value IN or NOT IN clauses.
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.
QgsExpressionNode * clone() const override
Generate a clone of this node.
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
An expression node which takes it value from a feature's field.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
virtual QSet< QString > referencedFunctions() const =0
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.
Abstract base class for all nodes that can appear in an expression.
virtual QString dump() const
Returns a string dump of the expression node.
static const QString EXPR_FIELDS
Inbuilt variable name for fields storage.
QgsExpressionNode * clone() const override
Generate a clone of this node.
~QgsExpressionNodeCondition() override
An expression node for expression functions.
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
static const QList< QgsExpressionFunction * > & Functions()
QVariant eval(QgsExpression *parent, const QgsExpressionContext *context)
Evaluate this node with the given context and parent.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
bool lazyEval() const
true if this function should use lazy evaluation.
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.
QList< QgsExpressionNodeCondition::WhenThen * > WhenThenList
QgsExpressionNode * clone() const override
Generate a clone of this node.
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.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
QgsExpressionNode::NodeList * clone() const
Creates a deep copy of this list. Ownership is transferred to the caller.
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 name() const
The name of the function.
A representation of the interval between two datetime values.
virtual bool needsGeometry() const =0
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.
int fieldNameIndex(const QString &fieldName) const
Utility method to get attribute index from name.
A abstract base class for defining QgsExpression functions.
A list of expression nodes.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QList< const QgsExpressionNode * > nodes() const override
Returns a list of all nodes which are used in this expression.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
QList< QgsExpressionNode * > list()
Gets a list of all the nodes.
QgsExpressionNodeUnaryOperator::UnaryOperator op() const
Returns the unary operator.
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...
An expression node for literal values.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate 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.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
A unary node is either negative as in boolean (not) or as in numbers (minus).
QSet< QString > referencedFunctions() const override
Returns a set of all functions which are used in this expression.
A binary expression operator, which operates on two values.
QString dump() const override
Dump this node into a serialized (part) of an expression.
WhenThen(QgsExpressionNode *whenExp, QgsExpressionNode *thenExp)
A combination of when and then.
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.
QString text() const
Returns a the name of this operator without the operands.
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
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.
QgsFeature feature() const
Convenience function for retrieving the feature for the context, if set.
QgsExpressionNodeCondition::WhenThen * clone() const
Gets a deep copy of this WhenThen combination.
virtual bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const =0
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.
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.
int count() const
Returns the number of nodes in the list.
bool prepareNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual preparation method Errors are reported to the parent.
void append(QgsExpressionNode *node)
Takes ownership of the provided node.
QVariant evalNode(QgsExpression *parent, const QgsExpressionContext *context) override
Abstract virtual eval method Errors are reported to the parent.
virtual QList< const QgsExpressionNode * > nodes() const =0
Returns a list of all nodes which are used in this expression.
QgsExpressionNode * node() const
Returns the expression node.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
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.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
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.
virtual bool prepare(const QgsExpressionNodeFunction *node, QgsExpression *parent, const QgsExpressionContext *context) const
This will be called during the prepare step() of an expression if it is not static.
bool isStatic(QgsExpression *parent, const QgsExpressionContext *context) const override
Returns true if this node can be evaluated for a static value.
QgsExpressionFunction * function(const QString &name) const
Fetches a matching function from the context.
bool needsGeometry() const override
Abstract virtual method which returns if the geometry is required to evaluate this expression...
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
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.
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.
QSet< QString > referencedVariables() const override
Returns a set of all variables which are used in this expression.
QVariant value() const
The value of the literal.
bool hasNamedNodes() const
Returns true if list contains any named nodes.
QSet< QString > referencedColumns() const override
Abstract virtual method which returns a list of columns required to evaluate this node...
int fnIndex() const
Returns the index of the node's function.
QgsExpressionNode::NodeType nodeType() const override
Gets the type of this node.
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.
static bool validateParams(int fnIndex, QgsExpressionNode::NodeList *args, QString &error)
Tests whether the provided argument list is valid for the matching function.