Repository navigation
N°10120 - Filtered classes in subqueries produce invalid SQL - #1059
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The query cache key omits the projection flag, allowing cached full projections to reintroduce invalid scalar subqueries.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Adds ID-only SQL projections for filtered scalar subqueries to prevent invalid multi-column IN/NOT IN queries.
Changes:
- Propagates an ID-only projection flag through search and union query builders.
- Requests ID-only output for nested queries.
- Modernizes expression formatting.
| File | Description |
|---|---|
core/sqlobjectquerybuilder.class.inc.php |
Builds ID-only projections when requested. |
core/oql/expression.class.inc.php |
Requests ID-only nested queries and applies formatting updates. |
core/dbunionsearch.class.php |
Propagates the flag through union branches. |
core/dbsearch.class.php |
Adds the flag to query-building APIs. |
core/dbobjectsearch.class.php |
Passes the flag into the SQL builder. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The projection flag is consistently propagated through the affected query-building paths, and all changed PHP files pass syntax validation.
Review effort: Balanced
Findings: None

Base information
Symptom (bug) / Objective (enhancement)
iTop can apply access-control filters to classes used only in OQL joins. If enabled, some
IN/NOT INsubqueries generate invalid SQL.The subqueries are expected to select only the object identifier, but they instead select all attributes of the object. MySQL then raises:
mysql_errno = 1241 mysql_error = Operand should contain 1 column(s)
Reproduction procedure (bug)
I don't know, raised by the unit tests
DBObjectSearch::ApplyDataFilters()applies access-control filters to joined classes as well as selected classes.For a nested
IN/NOT INquery,NestedQueryExpressionrequests an ID-only projection by passing empty attribute lists. However, applying joined-class filters can rebuild the nested search as aDBUnionSearch. The ID-only projection request is not explicitly preserved through this rebuilt query, so the SQL query builder generates the complete object projection for each subquery branch.This produces a multi-column subquery where SQL requires exactly one column.
Proposed solution (bug and enhancement)
Add an explicit ID-only projection flag for scalar subqueries and propagate it through the complete query-building path:
NestedQueryExpressionrequests ID-only output when rendering a nested SQL query.DBSearch::MakeSelectQuery()andGetSQLQuery()propagate this requirement.DBObjectSearchandDBUnionSearchpreserve it when building filtered or union queries.SQLObjectQueryBuilderselects only object identifiers when the flag is enabled.Normal object queries keep their existing projections. The existing
OQLTest::testMakeSelectQuery()regression case verifies that nestedIN/NOT INqueries remain valid when joined-class filtering is enabled.Checklist before requesting a review
OQLTest::testMakeSelectQuery()