[SalesForce] SOQL with polymorphic fields

Confused about the behavior of polymorphic fields in SOQL, sometimes you can select parental fields through a polymorphic relationship and sometimes you cannot. For example on Task with Who (polymorphic to Lead or Contact),

Select Who.Name, Who.Id from Task

Name and Id Works for all polymorphic relationships as far as I can tell.

Select Who.Email, Who.Phone from Task

No error but no data is returned, although for some polymorphic fields like Case.Owner.Email this works without issue. Email and Phone exists on both Lead and Contact.

Select Who.Birthdate from Task where Who.Type = 'Contact'

Gives error: No such column 'Birthdate' on entity 'Name'. Birthdate exists on Contact but not Lead, but doesn't matter if I filter only Contacts or not.

Select Who.FirstName from Task

Works, FirstName exists on both Contact and Lead. Why doesn't Email, Phone, etc also work?

Just trying to understand the rules on when we can select parental fields from polymorphic relationships, general rule of thumb seems to be it will work if the Field name exists on all polymorphic objects and the results do not have mixed objects types but then there are some exceptions to this. We are an ISV and need a predictable way of knowing when we can allow our users to select from polymorphic fields and when we need to restrict it. Any insight would be helpful.

Best Answer

There's a table called the "Name" object. Fields that can reference more than one object, including Owner fields, Who and What on task/events, and other types of fields might be "name pointing." This facilitates the ability to reference multiple objects, but limits what you can do with queries. If you're not sure, run a Describe on a field and see if "isNamePointing" is true. You can access all the fields of the "Name" object, but no others are available by default. There's a feature in pilot (since version 26... sigh) called TYPEOF under the Understanding Polymorphic Keys documentation. You can request it for developer accounts (and only developer accounts, as far as I can tell) that changes those polymorphic name fields into something a bit more palatable. You won't be using it in your ISV project for some time yet, though, apparently.