@@ -84,7 +84,7 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
8484	private  Schema.ChildRelationship  relationship ;
8585	private  Map <Schema .ChildRelationship , fflib_QueryFactory > subselectQueryMap ;
8686
87- 	private  String  getFieldPath (String  fieldName ){
87+ 	private  String  getFieldPath (String  fieldName , Schema. sObjectType   relatedSObjectType ){
8888		if (! fieldName .contains (' .'  )){ // single field
8989			Schema .SObjectField  token  =  fflib_SObjectDescribe .getDescribe (table ).getField (fieldName .toLowerCase ());
9090			if (token  ==  null )
@@ -107,8 +107,21 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
107107				fflib_SecurityUtils .checkFieldIsReadable (lastSObjectType , token );
108108			}
109109
110- 			if (token  !=  null  &&  i .hasNext () &&  tokenDescribe .getSoapType () ==  Schema .SoapType .ID ){
111- 				lastSObjectType  =  tokenDescribe .getReferenceTo ()[0 ]; // if it's polymorphic doesn't matter which one we get
110+ 			if  (token  !=  null  &&  i .hasNext () &&  tokenDescribe .getSoapType () ==  Schema .SoapType .ID ) {
111+ 				List <Schema .sObjectType > relatedObjs  =  tokenDescribe .getReferenceTo (); // if it's polymorphic, it matters which one we use - i.e. Lead.Owner is GROUP|USER and each has different fields.
112+ 
113+ 				if  (relatedObjs .size () ==  1  ||  relatedSObjectType  ==  null ) {
114+ 					lastSObjectType  =  relatedObjs [0 ]; // caller did not specify the one to use or there's only one so use the first one
115+ 				}
116+ 				else {
117+ 					for  (Schema .sObjectType  sot  :  relatedObjs ) {
118+ 						if  (fflib_SObjectDescribe .getDescribe (sot ).getDescribe ().getSObjectType () ==  relatedSObjectType ) {
119+ 							lastSObjectType  =  sot ;
120+ 							break ;
121+ 						}
122+ 					}
123+ 				}
124+ 
112125				fieldPath .add (tokenDescribe .getRelationshipName ());
113126			}else  if (token  !=  null  &&  ! i .hasNext ()){
114127				fieldPath .add (tokenDescribe .getName ());
@@ -122,6 +135,10 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
122135
123136		return  String .join (fieldPath ,' .'  );
124137	}
138+ 	
139+ 	private  String  getFieldPath (String  fieldName ) {
140+ 		return  this .getFieldPath (fieldName , null );
141+ 	}
125142
126143	@TestVisible
127144	private  static  String  getFieldTokenPath (Schema.SObjectField  field ){
@@ -197,16 +214,27 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
197214		this .sortSelectFields  =  doSort ;
198215		return  this ;
199216	}
200- 	
201217	/**  
202218	 * Selects a single field from the SObject specified in {@link  #table}. 
203219	 * Selecting fields is idempotent, if this field is already selected calling this method will have no additional impact. 
204220	 * @param  fieldName  the API name of the field to add to the query's SELECT clause. 
205221	 **/  
206222	public  fflib_QueryFactory  selectField (String  fieldName ){ 		
207- 		fields .add ( getFieldPath (fieldName ) );
223+ 		fields .add ( getFieldPath (fieldName , null ) );
224+ 		return  this ;
225+ 	}
226+ 
227+ 	/**  
228+ 		* Selects a single field from the SObject specified in {@link  #table}. 
229+ 		* Selecting fields is idempotent, if this field is already selected calling this method will have no additional impact. 
230+ 		* @param  fieldName  the API name of the field to add to the query's SELECT clause. 
231+ 		* @param  relatedSObjectType  the related sObjectType to resolve polymorphic object fields. 
232+ 	 **/  
233+ 	public  fflib_QueryFactory  selectField (String  fieldName , Schema.sOBjectType  relatedObjectType ) {
234+ 		fields .add (getFieldPath (fieldName , relatedObjectType ));
208235		return  this ;
209- 	} 
236+ 	}
237+ 	
210238	/**  
211239	 * Selects a field, avoiding the possible ambiguity of String API names. 
212240	 * @see  #selectField(String) 
@@ -760,6 +788,7 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
760788			this .setMessage ( ' Invalid field \' ' + fieldName + ' \'  for object \' ' + objectType + ' \' '   );
761789		}
762790	}
791+ 
763792	public  class  InvalidFieldSetException  extends  Exception {}
764793	public  class  NonReferenceFieldException  extends  Exception {}
765794	public  class  InvalidSubqueryRelationshipException  extends  Exception {}	
0 commit comments