@@ -69,13 +69,15 @@ bool QueryExecutorColumns::exec()
6969 context->resultColumns << resultColumn; // store it in context for later usage by any step
7070 }
7171
72- // qDebug() << "before: " << context->processedQuery;
72+ // qDebug() << "before: " << context->processedQuery;
7373 // Update query
7474 select->rebuildTokens ();
75- wrapWithAliasedColumns (select.data ());
75+ // #5179 does not seem to be needed anymore, because query executor alias is applied always in the main column loop above.
76+ // Keeping the commented reference here for a while, but to be removed in future (due to end of 2025).
77+ // wrapWithAliasedColumns(select.data());
7678 updateQueries ();
7779
78- // qDebug() << "after: " << context->processedQuery;
80+ // qDebug() << "after: " << context->processedQuery;
7981
8082 return true ;
8183}
@@ -176,11 +178,13 @@ SqliteSelect::Core::ResultColumn* QueryExecutorColumns::getResultColumnForSelect
176178 }
177179 }
178180
179- selectResultColumn->asKw = true ;
180181 if (!col.alias .isNull ())
181- selectResultColumn->alias = col.alias ;
182- else
183- selectResultColumn->alias = resultColumn->queryExecutorAlias ;
182+ selectResultColumn->expr ->column = col.alias ;
183+
184+ // #5179 duplicate of the same source table columns (but with different table alias) requires executor alias to be applied
185+ // always and immediately here to get proper results.
186+ selectResultColumn->asKw = true ;
187+ selectResultColumn->alias = resultColumn->queryExecutorAlias ;
184188
185189 // If this alias was already used we need to use sequential alias
186190 static_qstring (aliasTpl, " %1:%2" );
@@ -212,63 +216,6 @@ bool QueryExecutorColumns::isRowIdColumnAlias(const QString& alias)
212216 return false ;
213217}
214218
215- void QueryExecutorColumns::wrapWithAliasedColumns (SqliteSelect* select)
216- {
217- // Wrap everything in a surrounding SELECT and given query executor alias to all columns this time
218- TokenList sepTokens;
219- sepTokens << TokenPtr::create (Token::OPERATOR, " ," ) << TokenPtr::create (Token::SPACE, " " );
220-
221- bool first = true ;
222- TokenList outerColumns;
223- QStringList columnNamesUsed;
224- QString baseColName;
225- QString colName;
226- static_qstring (colNameTpl, " %1:%2" );
227- for (QueryExecutor::ResultColumnPtr& resCol : context->resultColumns )
228- {
229- if (!first)
230- outerColumns += sepTokens;
231-
232- // If alias was given, we use it. If it was anything but expression, we also use its display name,
233- // because it's explicit column (no matter if from table, or table alias).
234- baseColName = QString ();
235- if (!resCol->queryExecutorAlias .isNull ())
236- baseColName = resCol->alias ;
237- else if (!resCol->expression )
238- baseColName = resCol->column ;
239-
240- if (!baseColName.isNull ())
241- {
242- colName = baseColName;
243- for (int i = 1 ; columnNamesUsed.contains (colName, Qt::CaseInsensitive); i++)
244- colName = colNameTpl.arg (resCol->column , QString::number (i));
245-
246- columnNamesUsed << colName;
247- outerColumns << TokenPtr::create (Token::OTHER, wrapObjIfNeeded (colName));
248- outerColumns << TokenPtr::create (Token::SPACE, " " );
249- outerColumns << TokenPtr::create (Token::KEYWORD, " AS" );
250- outerColumns << TokenPtr::create (Token::SPACE, " " );
251- }
252- outerColumns << TokenPtr::create (Token::OTHER, resCol->queryExecutorAlias );
253- first = false ;
254- }
255-
256- for (QueryExecutor::ResultRowIdColumnPtr& rowIdColumn : context->rowIdColumns )
257- {
258- for (QString& alias : rowIdColumn->queryExecutorAliasToColumn .keys ())
259- {
260- if (!first)
261- outerColumns += sepTokens;
262-
263- outerColumns << TokenPtr::create (Token::OTHER, alias);
264- first = false ;
265- }
266- }
267-
268- // QString t = outerColumns.detokenize(); // keeping it for debug purposes
269- select->tokens = wrapSelect (select->tokens , outerColumns);
270- }
271-
272219bool QueryExecutorColumns::isRowIdColumn (const QString& columnAlias)
273220{
274221 // In case of "SELECT * FROM (SELECT * FROM test);" the SelectResolver will return ROWID columns twice for each table listed,
0 commit comments