Skip to content

N°10120 - Filtered classes in subqueries produce invalid SQL - #1059

Merged
steffunky merged 2 commits into
support/3.2from
issue/10120_filtered_subqueries_invalid
Oct 1, 2026
Merged

steffunky merged 2 commits into
support/3.2from
issue/10120_filtered_subqueries_invalid

Conversation

@steffunky

Copy link
Copy Markdown
Member

Base information

Question Answer
Related to a SourceForge thread / Another PR / A GitHub Issue / Combodo ticket? N°10120, related to N°8532 and N°10075
Type of change? Bug fix

Symptom (bug) / Objective (enhancement)

iTop can apply access-control filters to classes used only in OQL joins. If enabled, some IN/NOT IN subqueries 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 IN query, NestedQueryExpression requests an ID-only projection by passing empty attribute lists. However, applying joined-class filters can rebuild the nested search as a DBUnionSearch. 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:

  • NestedQueryExpression requests ID-only output when rendering a nested SQL query.
  • DBSearch::MakeSelectQuery() and GetSQLQuery() propagate this requirement.
  • DBObjectSearch and DBUnionSearch preserve it when building filtered or union queries.
  • SQLObjectQueryBuilder selects only object identifiers when the flag is enabled.

Normal object queries keep their existing projections. The existing OQLTest::testMakeSelectQuery() regression case verifies that nested IN/NOT IN queries remain valid when joined-class filtering is enabled.

Checklist before requesting a review

  • I have performed a self-review of my code
  • I have tested all changes I made on an iTop instance; PHPUnit execution should be performed in the Docker environment
  • I have added or retained regression coverage through OQLTest::testMakeSelectQuery()
  • Is the PR clear and detailed enough so anyone can understand without digging in the code?

@steffunky steffunky added this to the 3.2.4 milestone Sep 29, 2026
@steffunky steffunky self-assigned this Sep 29, 2026
Copilot AI balanced review requested due to automatic review settings September 29, 2026 14:46
@steffunky steffunky added internal Work made by Combodo OQL labels Sep 29, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 High severity

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.

Comment thread core/dbobjectsearch.class.php
@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[High risk] Database query builder adds parameter to control subquery field selection.

The PR appears safe to merge based on the reviewed changes.

Summary

The PR propagates an ID-only projection request through nested-query and union SQL generation, and separates ID-only queries from full-projection queries in the query-structure cache.

  • Nested IN/NOT IN queries request object identifiers rather than full object projections.
  • The cache key now distinguishes the two projection modes.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[NestedQueryExpression] -->|ID-only request| B[DBSearch]
  B --> C[DBObjectSearch or DBUnionSearch]
  C --> D[SQLObjectQueryBuilder]
  D --> E[Identifier projection]
Loading

Reviews (2) · Last reviewed commit: "Avoid SQL cache to be shared between ids..."

Comment thread core/dbobjectsearch.class.php

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Resolved since last review (1)

@steffunky
steffunky merged commit 31a4e1a into support/3.2 Oct 1, 2026
2 checks passed
@steffunky
steffunky deleted the issue/10120_filtered_subqueries_invalid branch October 1, 2026 08:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Work made by Combodo OQL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants