0

I am trying to write a utility to export a SOQL query to a POCO / POJO, and it works so far using the describe API on the SObjects.

Is there a way to directly describe a specific SOQL query, including the fields inside a nested query or relationship?

2

No, there's no way to describe a SOQL query result. You'd need to combine the describe data with the structured JSON returned from the query endpoint.

The returned data is structured: nested objects and relationships are represented as nested objects in JSON, not as a flat column list. However, query results do not provide field-level type introspection details, so you'd need to correlate against the describe from the actual query result to obtain that.

1

There is soql-parser-js in npm/javascript if you want to break out a query into its different parts as an AST JSON object. Once you have the query parsed, you can do all sorts of transformations and what not to convert that object into whatever your desired POJO model is. I am not aware of anything similar that exists in apex, nor do i feel that something such as a tokenizer and lexer belong somewhere like apex.

Here is an example of a query with some nested queries and relationship fields for a quick reference:

Query:

SELECT Id, Name FROM Account WHERE Id IN ( SELECT AccountId FROM Contact WHERE LastName LIKE 'apple%' ) AND Id IN ( SELECT AccountId, Account.CreatedBy.Name FROM Opportunity WHERE isClosed = FALSE )

Parsed:

{
    "fields": [
        {
            "type": "Field",
            "field": "Id"
        },
        {
            "type": "Field",
            "field": "Name"
        }
    ],
    "sObject": "Account",
    "where": {
        "left": {
            "field": "Id",
            "operator": "IN",
            "valueQuery": {
                "fields": [
                    {
                        "type": "Field",
                        "field": "AccountId"
                    }
                ],
                "sObject": "Contact",
                "where": {
                    "left": {
                        "field": "LastName",
                        "operator": "LIKE",
                        "value": "'apple%'",
                        "literalType": "STRING"
                    }
                }
            }
        },
        "operator": "AND",
        "right": {
            "left": {
                "field": "Id",
                "operator": "IN",
                "valueQuery": {
                    "fields": [
                        {
                            "type": "Field",
                            "field": "AccountId"
                        },
                        {
                            "type": "FieldRelationship",
                            "field": "Name",
                            "relationships": [
                                "Account",
                                "CreatedBy"
                            ],
                            "rawValue": "Account.CreatedBy.Name"
                        }
                    ],
                    "sObject": "Opportunity",
                    "where": {
                        "left": {
                            "field": "isClosed",
                            "operator": "=",
                            "value": "FALSE",
                            "literalType": "BOOLEAN"
                        }
                    }
                }
            }
        }
    }
}
2
  • So close, it unfortunately doesn't seem to show the field types.
    – Kyle J V
    Apr 12 at 15:59
  • You just need to mix this with your describe data. There is no way a parser is going to have access to your metadata to know what your field types are. So when you are say... looping through the select fields on a query for an sObject, have a map of the sobjects fields and you can easily add a new property to this pojo model that is FieldType. Apr 12 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.