2

I am building a dynamic SOSL Query

searchText = 'AB-C';

searchquery = 'FIND {'+ searchText + '} IN all FIELDS RETURNING Account(   id, name, ownerid,website, CMFL__Oppty_Count__c WHERE '+ condition +'  order by  createddate DESC  )';
                    System.debug(searchquery);

Debug

FIND {AB-C*} IN all FIELDS RETURNING Account( id, name,Additional_domains__c, ownerid,website WHERE (Website_Domain__c='ab\-c.com' OR Additional_domains__c like '%ab\-c.com%') order by createddate DESC )

When the query is run it returns an error

System.QueryException: line 1:8 mismatched character '-' expecting '}'

I thought i havent escaped the string for special chars and hence this error. I removed the '-' in AB-C and now i get this error on the where condition where i have escaped in the where conditions

Invalid string literal 'ab\-c.com'. Illegal character sequence '\-' in string literal.

When should i escape the string and when i should not while creating a dynamic query

2 Answers 2

6

The SOSL Reference describes the reserved characters in the search query (FIND clause):

The following characters are reserved: ? & | ! { } [ ] ( ) ^ ~ * : \ " ' + -

Reserved characters, if specified in a text search, must be escaped (preceded by the backslash \ character) to be properly interpreted. An error occurs if you do not precede reserved characters with a backslash. This is true even if the SearchQuery is enclosed in double quotes.

So you do need to escape the hyphen in your FIND clause with a backslash, which itself must be escaped (yielding \\-) in an Apex string literal.

In the SOSL WHERE clause, however, the hyphen is not a special character and does not need to be escaped.

1
  • +1, I got it all wrong. Commented Mar 15, 2019 at 12:29
0

According to the SOSL Reference mentioned by David Reed, this is a code snippet which should help in Java (using Apache Commons Text):

public class StringUtils {

    /**
     * Reserved characters which need to be escaped in SOSL
     * https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm
     */
    public static final CharSequenceTranslator ESCAPE_SOSL;

    static {
        final Map<CharSequence, CharSequence> escapeSoslMap = new HashMap<>();
        escapeSoslMap.put("?", "\\?");
        escapeSoslMap.put("&", "\\&");
        escapeSoslMap.put("|", "\\|");
        escapeSoslMap.put("!", "\\!");
        escapeSoslMap.put("{", "\\{");
        escapeSoslMap.put("}", "\\}");
        escapeSoslMap.put("[", "\\[");
        escapeSoslMap.put("]", "\\]");
        escapeSoslMap.put("(", "\\(");
        escapeSoslMap.put(")", "\\)");
        escapeSoslMap.put("^", "\\^");
        escapeSoslMap.put("~", "\\~");
        escapeSoslMap.put("*", "\\*");
        escapeSoslMap.put(":", "\\:");
        escapeSoslMap.put("\\", "\\\\");
        escapeSoslMap.put("\"", "\\\"");
        escapeSoslMap.put("'", "\\'");
        escapeSoslMap.put("+", "\\+");
        escapeSoslMap.put("-", "\\-");
        ESCAPE_SOSL = new AggregateTranslator(new LookupTranslator(Collections.unmodifiableMap(escapeSoslMap)));
    }

    /**
     * Escape SOSL reserved characters
     * https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_sosl_find.htm
     */
    public static final String escapeSosl(final String input) {
        return ESCAPE_SOSL.translate(input);
    }
}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .