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
gpervukhingpervukhin 

SOQL parser problem?

Hi, everybody. I want to share my thoughts with you about the problem that I met with SOQL parser.

 

Here is the query that I tried to execute:

database.query('SELECT Id FROM Task WHERE ((AccountId IN (SELECT Id FROM Account WHERE Name like \'%test%\')) AND (ReminderDateTime > 2013-03-01T00:00:00Z)) AND (Status != \'Completed\')');

 

as a result I've got the following exception:

System.QueryException: Semi join sub-selects are only allowed at the top level WHERE expressions and not in nested WHERE expressions.

 

Let's analyze the query:

C1 = AccountId IN (SELECT Id FROM Account WHERE Name like \'%test%\')

C2 = ReminderDateTime > 2013-03-01T00:00:00Z

C3 = Status != \'Completed\'

 

Result:

... Where ((C1) AND (C2)) AND (C3)

 

 

Let's do another similar test. Everything works, if I reorganize the query in this way:

database.query('SELECT Id FROM Task WHERE (AccountId IN (SELECT Id FROM Account WHERE Name like \'%test%\')) AND (ReminderDateTime > 2013-03-01T00:00:00Z) AND (Status != \'Completed\')');

 

Analysis:

... Where (C1) AND (C2) AND (C3)

 

 

So, I can't see a real problem in the first query.

 

p.s.1: I do not exclude that this could be my error.

p.s.2: I will be very grateful for your answers, but please do not suggest to remove brackets, because this query is generated in code, and please suggest me to reorganize the query only if it's really incorrect.

sfdcfoxsfdcfox

The SOQL layer doesn't optimize the query; it leaves that for the SQL optimizer. So, nested parenthesis creates nested filters. It doesn't matter that SQL will optimize away the extra layers, because the parser will prevent it from ever reaching the database layer. That prevents a class of confusing conditions, such as ((X) AND (Y)) AND (Z) works but ((X) OR (Y)) AND Z doesn't (you can't remove the nesting and get the same execution path assumption). Therefore, remove the nesting unless you need it. They are not technically the same, because the SOQL parser is not a query optimizer.

gpervukhingpervukhin

, thank you for your reply.

 

It's very strange that SOQL parser doesn't optimize the query.

hemant keni 20hemant keni 20

I run the above query and i got the same error.

By looking at the error, i just removed extra round brackets after where clause and the query gets executed.

database.query('SELECT Id FROM Task WHERE (AccountId IN (SELECT Id FROM Account WHERE Name like \'%test%\')) AND (ReminderDateTime > 2013-03-01T00:00:00Z) AND (Status != \'Completed\' )');

 

GennadiyGennadiy
hemant keni 20, in my original question I've already written how to make it working by just removing extra brackets. But my question was: why it does not work if queries are the same logically? I wasn't able to remove these brackets, because the query was generated dynamically in a query builder that could not be modified. So, it looks like the right answer is still "My both queries would be identical in classic SQL, but SOQL parser does not make optimization at the analysis phase and can't remove extra brackets".

In any case, thank you for interest in this rather old thread.