function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
THustonTHuston 

Partner API to get QueryResult metadata

I'm working on an ODA plugin for the BIRT project.

 

The nature of the ODA requires a prepare() of the query to collect a list of fields and the field's data type before rows are read in.

 

Does there exist any Partner API that would return a sample QueryResult (metadata QR) that has no null objects?

I can't just run the query and traverse the first row.

   select name, (select status from Account.Cases) from Account

   If the first Account has no Cases, then I will never know that there is a status Field returned.

 

My only options appear to be

1) read all of the rows until there are no null SObjects then start over for the execute()

2) do a massively complex bit of String parsing to find all the Fields in the SelectClauses and then parse and match those to the intended SObject and get the dataType binding.describeSObject("SObject").getFields()[1-n].getType()

 

The first is too inefficient to consider.

The second is proving too complex.  Every time I find a query that does not work, I realize a major assumption about the syntax is invalid and must rework my whole algorithm. 

 

BTW: The BNF is incomplete.

This is not accounted for (among, I'm sure several others):

SELECT Id, Name FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity )

 

 

Message Edited by THuston on 03-24-2010 07:02 AM
Best Answer chosen by Admin (Salesforce Developers) 
THustonTHuston

I found a way to do this that works pretty well using v17 Partner WSDL. 

Have yet to upgrade to v18 and add in Aggregate functionality.

 

The only time you would lose Fields is in the SubSelect (Parent->Child) queries.

So,

I parse the query only to separate the Field Selects.  Then I isolate the first thing in the FROM clause. 

For the main/outer query this is the Parent to be used with the inner RelationshipName:

ChildRelationship [] crs = binding.describeObject( parentObject ).getChildRelationships();

Loop and compare to crs[i].getChildSObject();

 

Once I have all the queries, I add Limit 1 and then traverse the QueryResult to find all the Fields that can be returned and then I can loop and find the dataType.

 

I lose any Alias names from the SOQL and I need a way to detect a request for ID since it is always returned, but I've got it.

Hopefully AggregateResult won't mess me up too much in the next version.

All Answers

THustonTHuston

I found a way to do this that works pretty well using v17 Partner WSDL. 

Have yet to upgrade to v18 and add in Aggregate functionality.

 

The only time you would lose Fields is in the SubSelect (Parent->Child) queries.

So,

I parse the query only to separate the Field Selects.  Then I isolate the first thing in the FROM clause. 

For the main/outer query this is the Parent to be used with the inner RelationshipName:

ChildRelationship [] crs = binding.describeObject( parentObject ).getChildRelationships();

Loop and compare to crs[i].getChildSObject();

 

Once I have all the queries, I add Limit 1 and then traverse the QueryResult to find all the Fields that can be returned and then I can loop and find the dataType.

 

I lose any Alias names from the SOQL and I need a way to detect a request for ID since it is always returned, but I've got it.

Hopefully AggregateResult won't mess me up too much in the next version.

This was selected as the best answer
COZYROCCOZYROC

I have the same problem. I have posted suggestion to Salesforce to implement enhancement to their API here.