---
schema_version: "1"
id: 732fafb6b2c3f57153952e525b2d7fb471fbd5d8718c80696af298cfc35e4904
title: Prevent Field Name Collisions in Managed SOQL Queries
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/apex_manpkgs_dynamic_soql.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_manpkgs_dynamic_soql.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 2f1ecec73bde972c719bcc08e76d5fa857ad76758969a1fd00deb80036c67145
description: As an independent software vendor (ISV) or managed package developer, prevent duplicate field name errors in dynamic SOQL when a packaged custom field and a subscriber custom field share the same API name. Build a Database.QueryOptions object with explicitNamespace set to true, and pass it as a bind variable in the SOQL SET OPTIONS clause.
---
# Prevent Field Name Collisions in Managed SOQL Queries

As an independent software vendor (ISV) or managed package developer, prevent duplicate field name errors in dynamic SOQL when a packaged custom field and a subscriber custom field share the same API name. Build a Database.QueryOptions object with explicitNamespace set to true, and pass it as a bind variable in the SOQL SET OPTIONS clause.

## Understand Namespace Shadowing in Managed Packages

In managed Apex, if an unqualified custom field or relationship name matches both a packaged and a local field, the SOQL parser gives precedence to the package’s [default namespace](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_namespace_prefix.htm "The Salesforce application supports the use of namespace prefixes. Namespace prefixes are used in managed AppExchange packages to differentiate custom object and field names from names used by other organizations."). This default assumption keeps packaged SOQL readable, but it can cause duplicate field name errors if a subscriber creates a local custom field with the same API name as a packaged field.

For example, suppose that your managed package uses the namespace ExPackageNS and includes an Age\_\_c field on Account. A subscriber org also creates an unmanaged Age\_\_c field on Account. In packaged Apex at API version 34.0 and later, this dynamic query fails with a duplicate field name error because both field references resolve to the packaged field.

// Fails in a subscriber org that also has Age\_\_c
List<Account> results = Database.query(
    'SELECT Id, Age\_\_c, ExPackageNS\_\_Age\_\_c FROM Account'
);

## How Explicit Namespace Resolution Works

The explicitNamespace property for Database.QueryOptions prevents namespace shadowing conflicts. You can query the subscriber’s local field, the packaged field, or both fields in the same dynamic SOQL query.

If you set explicitNamespace to true on a Database.QueryOptions object:

- An unqualified custom field or relationship name, such as Age\_\_c, resolves to the subscriber’s local field.
- A namespace-qualified name, such as ExPackageNS\_\_Age\_\_c, resolves to the packaged field.
- If the subscriber org doesn’t have the local field, the query doesn’t fall back to the packaged field. To query the packaged field, use the namespace-qualified name.

That resolution applies across SELECT, WHERE, GROUP BY, HAVING, ORDER BY, foreign key traversal, aggregates, DISTANCE expressions, aliased expressions, relationship names, and subqueries or semi-joins that inherit options from the outer query.

Setting explicitNamespace to false is the same as leaving it unset. Package namespace precedence matching is applied.

## Query Package and Subscriber Fields with Dynamic SOQL

Use dynamic SOQL when you need both the packaged field and the subscriber field in the same query, or when you reference a subscriber field that didn’t exist when the package was compiled.

Even when SET OPTIONS is present, static SOQL that selects both an unqualified field and its namespace-qualified counterpart fails at compile time because static SOQL can reference only fields that existed when the packaged class was compiled. Therefore, referencing a subscriber’s local field requires dynamic SOQL.

In this example, the subscriber’s local Age\_\_c field doesn’t exist when ExPackageNS\_\_Age\_\_c is compiled, so the Database.query method is used to query the fields dynamically.

Database.QueryOptions opts = Database.QueryOptions.builder()
    .withExplicitNamespace(true)
    .build();

// Age\_\_c -> subscriber-local field
// ExPackageNS\_\_Age\_\_c -> packaged field
List<Account> results = Database.query(
    'SELECT Id, Name, Age\_\_c, ExPackageNS\_\_Age\_\_c FROM Account SET OPTIONS :opts',
    AccessLevel.USER\_MODE
);

This example uses the Database.queryWithBinds method.

Database.QueryOptions opts = Database.QueryOptions.builder()
    .withExplicitNamespace(true)
    .build();

List<Account> results = Database.queryWithBinds(
    'SELECT Id, Name, Age\_\_c, ExPackageNS\_\_Age\_\_c FROM Account SET OPTIONS :opts',
    new Map<String, Object\>{ 'opts' => opts },
    AccessLevel.USER\_MODE
);

In this example, only the subscriber’s local field is queried.

Database.QueryOptions opts = Database.QueryOptions.builder()
    .withExplicitNamespace(true)
    .build();

// Age\_\_c resolves to the subscriber field only.
List<Account> results = Database.query(
    'SELECT Id, Age\_\_c FROM Account SET OPTIONS :opts'
);

You can also pass Database.QueryOptions through related dynamic SOQL methods that support binds, including Database.countQuery, Database.countQueryWithBinds, Database.getQueryLocator, and Database.getQueryLocatorWithBinds.

## Considerations

Review these considerations when working with Database.QueryOptions and the SET OPTIONS clause in dynamic SOQL queries.

- Place SET OPTIONS after other query clauses, such as WHERE, GROUP BY, ORDER BY, LIMIT, and OFFSET, and before FOR UPDATE.
- Put SET OPTIONS on the outermost query only. Nested queries inherit the outer options for explicit namespace resolution.
- Use the :optionsVariable bind syntax in Apex only. It isn’t supported when you run SOQL directly through REST API or SOAP API.
- In dynamic SOQL, resolve the bind directly to a Database.QueryOptions variable. Don’t use expressions, such as :wrapper.opts or :getOpts().
- Construct Database.QueryOptions only through Database.QueryOptions.builder(). After build(), the object is immutable.
- Only the Database.QueryOptions properties that you explicitly set are applied.

## Error Handling

This table details some possible exceptions that can occur when working with Database.QueryOptions and builder options in Apex.

| Error Type | Condition | Exception |
| --- | --- | --- |
| Compile-time | Bind variable isn’t of type Database.QueryOptions. | Compile error |
| Runtime | Null Database.QueryOptions passed to SET OPTIONS. | System.QueryException |
| Runtime | Apex class API version is below the minimum required for a builder option. | System.QueryException |

#### See Also

- [Namespace Prefix](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_namespace_prefix.htm "The Salesforce application supports the use of namespace prefixes. Namespace prefixes are used in managed AppExchange packages to differentiate custom object and field names from names used by other organizations.")
- [Dynamic SOQL](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dynamic_soql.htm "Dynamic SOQL refers to the creation of a SOQL string at run time with Apex code. Dynamic SOQL enables you to create more flexible applications. For example, you can create a search based on input from an end user or update records with varying field names.")
- [_Apex Reference Guide_: Database.QueryOptions Class](https://developer.salesforce.com/docs/atlas.en-us.264.0.apexref.meta/apexref/apex_class_Database_QueryOptions.htm)
- [_Apex Reference Guide_: Database.QueryOptionsBuilder Class](https://developer.salesforce.com/docs/atlas.en-us.264.0.apexref.meta/apexref/apex_class_Database_QueryOptionsBuilder.htm)
- [_SOQL and SOSL Reference_: SET OPTIONS](https://developer.salesforce.com/docs/atlas.en-us.264.0.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_set_options.htm)