Skip to content

Fix PE056: Deep aggregate unwrapping for QUERY resolution#12

Merged
starseeker merged 4 commits intotreatfrom
copilot/fix-deep-aggregate-unwrapping
Feb 6, 2026
Merged

Fix PE056: Deep aggregate unwrapping for QUERY resolution#12
starseeker merged 4 commits intotreatfrom
copilot/fix-deep-aggregate-unwrapping

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 6, 2026

QUERY expressions failed with PE056 when the source was a named aggregate type or SELECT-of-named-aggregates. The resolver performed shallow TYPEis_aggregate() checks that didn't unwrap through typedef chains.

TYPE my_set = SET OF INTEGER;
END_TYPE;

ENTITY test;
    numbers : my_set;
WHERE
    -- Previously failed with PE056
    WR1 : SIZEOF(QUERY(n <* SELF.numbers | n > 0)) >= 0;
END_ENTITY;

Changes

Added TYPEget_aggregate_base() helper

  • Unwraps through typedef chains to extract aggregate element type
  • Returns NULL if type doesn't resolve to an aggregate
  • Exported in include/express/type.h

Updated QUERY resolution (src/express/resolve.c)

  • Replaced shallow TYPEis_aggregate() with TYPEinherits_from(..., aggregate_)
  • Uses TYPEget_aggregate_base() to derive query variable type from named aggregates

Fixed TYPE_retrieve_aggregate() for SELECT-of-aggregates

  • Deep unwrapping via TYPEinherits_from() + TYPEget_aggregate_base()
  • Element type comparison now uses body->type instead of pointer equality (different aggregate definitions create separate Type instances for the same underlying type)
  • Added entity identity check for entity types

Test coverage

  • test/unitary_schemas/simple_query_test.exp - QUERY over defined aggregate
  • test/unitary_schemas/select_aggregate_test.exp - QUERY over SELECT-of-aggregates
  • test/unitary_schemas/query_named_aggregate.exp - Nested aggregates
  • Moved test/buggy/expr-src-aggregate.exp to passing tests

Out of scope

Flow-sensitive narrowing and TREAT syntax deferred to later PRs. AP242 styled_item WR3 still fails as expected.

Original prompt

PR 1 — Deep aggregate unwrapping (standards-aligned, low risk)

Goal: Fix PE056 cases where QUERY source is a named aggregate type or SELECT-of-named-aggregates by doing deep type unwrapping rather than shallow TYPEis_aggregate.
Agent input

Implement deep aggregate detection + element-type extraction used by the QUERY resolver and by TYPE_retrieve_aggregate():

Add a helper:

Type TYPEget_aggregate_base(Type t) (or better name: TYPEaggregate_base), exported in include/express/type.h, implemented in src/express/type.c.
It should unwrap through defined type chains until it hits an aggregate constructor (set_, bag_, list_, array_, aggregate_), and then return that aggregate’s element type (tb->base).
It must return NULL if t does not resolve to an aggregate.

Update QUERY resolution in src/express/resolve.c:

Replace shallow TYPEis_aggregate(expr->return_type) checks with TYPEinherits_from(expr->return_type, aggregate_).
When it’s an aggregate (possibly through typedefs), use TYPEget_aggregate_base() to derive the query variable type.

Update TYPE_retrieve_aggregate():

When iterating SELECT members, use TYPEinherits_from(member, aggregate_) and TYPEget_aggregate_base(member) rather than shallow TYPEis_aggregate and direct ->body->base.
Keep the existing “common element type” check: if different member aggregates have different element base types, return NULL.

Tests:

Add a small .exp schema under test/ that covers:
    a defined type TYPE my_set = SET OF INTEGER;
    a SELECT whose members are my_set and another defined aggregate (same element type)
    QUERY over a variable of the defined aggregate type
    QUERY over a variable of the SELECT-of-aggregates type (only if all SELECT members are aggregates; if you keep it strict, reflect that)
Ensure the tests verify pass behavior only (don’t add “must fail” tests unless the harness supports negative tests).

Non-goals in PR 1:

Do not implement flow-sensitive narrowing.
Do not implement TREAT syntax yet.
Do not change global typing rules for SELECT beyond the deep-unwrapping.

Acceptance criteria:

Existing behavior unchanged for inline aggregates.
Named aggregate QUERY sources work.
Any existing “buggy expr-src-aggregate.exp” test is moved into passing tests and passes.
AP242 may still fail on styled_item WR3 (expected); that’s for later PRs.

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 6, 2026 22:28
Co-authored-by: starseeker <238416+starseeker@users.noreply.github.com>
Co-authored-by: starseeker <238416+starseeker@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix deep aggregate unwrapping for QUERY source Fix PE056: Deep aggregate unwrapping for QUERY resolution Feb 6, 2026
Copilot AI requested a review from starseeker February 6, 2026 22:33
@starseeker starseeker marked this pull request as ready for review February 6, 2026 22:46
@starseeker starseeker merged commit 4e386ae into treat Feb 6, 2026
2 of 6 checks passed
@starseeker starseeker deleted the copilot/fix-deep-aggregate-unwrapping branch February 6, 2026 22:47
starseeker added a commit that referenced this pull request Feb 9, 2026
* Implement deep aggregate unwrapping for QUERY resolution (PE056 fix)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: starseeker <238416+starseeker@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants