SfSkills Domains Docs GitHub

Home / apex / apex-polymorphic-soql

apex-polymorphic-soql

Polymorphic SOQL with TYPEOF: querying Task.WhatId, Task.WhoId, ContentDocumentLink.LinkedEntityId, FeedItem.ParentId; fallback to Type filters; indexing and selectivity. NOT for subqueries or dot-notation traversal — use apex/apex-soql-relationship-queries. NOT for the Activity data model — use admin/activity-and-task-patterns.

Open the skill folder on GitHub


Apex Polymorphic SOQL

Activate when writing SOQL against polymorphic fields — Task.WhatId, Task.WhoId, Event.WhatId, ContentDocumentLink.LinkedEntityId, FeedItem.ParentId, Note.ParentId. Polymorphic fields reference multiple object types; field access requires TYPEOF or Type filters, and the platform's indexing rules are different from normal lookup fields.

Before Starting

Core Concepts

TYPEOF syntax

SELECT Id, Subject,
  TYPEOF What
    WHEN Account THEN Name, Industry
    WHEN Opportunity THEN Amount, StageName
    ELSE Name
  END
FROM Task
WHERE ActivityDate = TODAY

Per-row, the query returns fields of the matched target type. ELSE is optional — include it to cover unmatched cases.

Type filter fallback

SELECT Id, What.Name FROM Task WHERE What.Type = 'Account'

Post-filter, What.Name is safe because every match is an Account. Less flexible than TYPEOF but simpler.

Common polymorphic fields

Indexing

Polymorphic field equality on Id is selective (indexed). Filtering on .Type is a non-indexed filter — apply after an Id-selective filter.

Common Patterns

Pattern: TYPEOF with common-parent field

SELECT Id, Subject, What.Name, What.Type FROM Task WHERE Id IN :ids

What.Name works because Name is on every polymorphic target's parent. Avoids TYPEOF ceremony for common fields.

Pattern: TYPEOF for type-specific fields

Use when you need Industry (Account), Amount (Opportunity), etc. Only TYPEOF can project per-type fields.

Pattern: Two-step query

Query IDs and types; partition; re-query per type with full field lists. Useful when downstream logic per type is complex.

Decision Guidance

NeedPattern
Just Id, Type, NameFlat query with What.Name
Per-type fields in one passTYPEOF WHEN
One specific type onlyWHERE What.Type = 'Account'
Complex per-type processingQuery once, partition in Apex, re-query per type
  1. Identify the polymorphic field and its possible target objects.
  2. Decide per-type fields required.
  3. If varied per type, use TYPEOF; if one type only, use Type filter.
  4. Ensure Id or other selective filter is present — Type alone is non-selective.
  5. Apex-side: iterate results and use instanceof or .getSObjectType() to dispatch.
  6. Test with rows of each target type present.
  7. Measure query plan if performance-critical.

Review Checklist

Salesforce-Specific Gotchas

  1. Not all polymorphic fields support TYPEOF. Task, Event, ContentDocumentLink, FeedItem, Note do; verify for newer objects.
  2. Schema.SObjectType.Task.fields.WhatId.getReferenceTo() returns the full list of possible target types at runtime.
  3. TYPEOF cannot be used in subqueries (inner queries within SELECT list). Plan accordingly.

Output Artifacts

ArtifactDescription
Polymorphic query libraryReusable TYPEOF queries per field
Target-type catalogField → list of possible objects
Dispatcher helperApex utility routing by record type

Package files