# UNDF: UNDF-2026-000001205 --- a/OpenRPT/renderer/orutils.cpp +++ b/OpenRPT/renderer/orutils.cpp @@ -21,6 +21,7 @@ #include "orutils.h" #include +#include #include "../../MetaSQL/metasql.h" @@ -50,6 +51,9 @@ orQuery::orQuery( const QString &qstrPName, const QString &qstrSQL, if(rexp.indexIn(qstrParsedSQL) == -1) { // Parse through the passed SQL populating the parameters + // Use a QSet shadow for O(1) membership test so we do not scan the + // growing missingParamList (QStringList::contains is O(M)) on every iteration. + QSet missingParamSet; QRegExp re("(?:%(\\d+))|(?:\\$\"([^\"]*)\")"); while ((intStartIndex = re.indexIn(qstrParsedSQL,intStartIndex)) != -1) { @@ -60,8 +64,11 @@ orQuery::orQuery( const QString &qstrPName, const QString &qstrSQL, val = qstrlstParams.value(n).toString(); if(val.isNull()) { - // add this to the list of missing parameters - if(!missingParamList.contains(n)) + // add this to the list of missing parameters (dedup via hash set) + if(!missingParamSet.contains(n)) + { + missingParamSet.insert(n); missingParamList.append(n); + } } } else if(match[0] == '%') @@ -74,8 +81,12 @@ orQuery::orQuery( const QString &qstrPName, const QString &qstrSQL, else { // add this to the list of missing parameters + // dedup via hash set to avoid O(P*M) QStringList scan QString s = QString("%%1").arg(intParamNum); - if(!missingParamList.contains(s)) missingParamList.append(s); + if(!missingParamSet.contains(s)) { + missingParamSet.insert(s); + missingParamList.append(s); + } } } else