Skip to content

feat: support SOQL SET OPTIONS literals and query options binds - #167

Merged
kjonescertinia merged 2 commits into
mainfrom
ao/apex-parser-3/set-options
Oct 2, 2026
Merged

kjonescertinia merged 2 commits into
mainfrom
ao/apex-parser-3/set-options

Conversation

@nawforce

@nawforce nawforce commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Closes #165.

Standalone query() now accepts terminal SET OPTIONS (dataspace = '…', honorEmptyStrings = true|false) lists and whole query-options binds using the existing boundExpression : COLON expression rule. Inline Apex accepts query-options boundExpression syntax, verified against pre-release at API 68.0 with empty options, identifier/method-call binds, and count/aggregate queries. Inline literal lists remain rejected. Existing query/select/from/grouping contexts and bound-expression visitor reachability are preserved.

Bind expressions are parsed consistently across entry points without an identifier-only predicate. Parenthesized/member/method-call expressions and syntactically valid but inappropriate values such as :true, :'package', and :opts + 1 retain their expression AST for consumer diagnostics. Parsing acceptance is not a guarantee of Database.QueryOptions type or platform legality in dynamic SOQL. Execution-aware consumers must check bind types, supported placeholder/expression forms, and managed context; queryWithBinds() keys must be validated against the supplied map rather than resolved as static Apex variables. Current apex-ls lacks options-specific validation and does not parse arbitrary dynamic strings.

Primary evidence:

Context matrix and exact sanitized live probes record actual outcomes, including a map-only key with no same-named Apex variable. REST literal queries succeeded; dynamic Apex literals failed at runtime and inline literals failed compilation (with indirect compiler diagnostics). This separates live inline bind support from the documented managed-dynamic namespace behavior. An undocumented REST namespace Boolean was accepted by the org but is intentionally excluded from this grammar.

Validation: npm run init; npm run build (196 TypeScript tests, 195 JVM tests); SAMPLES=/Users/kevinjones/adt/apex-samples npm run systest against v1.4.0 (100 tests and 100 snapshots passed on the final build); commit hooks (ESLint/Prettier); git diff --check. GitHub CI for commit a9d5908 passed the full build and sample-system-test workflow. Regressions cover acceptance, malformed/misplaced clauses, unsupported literal values, identifier compatibility, permissive bind-expression parsing and traversal, and list/count/aggregate AST shape.

Limitations: no discoverable Data 360 objects and no managed package/subscriber setup, so DLO/DMO behavior and namespace semantics were not verified live. Object eligibility, bind value types and managed execution constraints remain semantic; standalone parsing cannot distinguish REST from dynamic Apex. No invented namespace-string forms, static namespace resolution, API gate, or subquery expansion.

Follow-up for apex-ls: adopt the parser dependency and add verified inline bind/standalone query regressions for bind traversal and list/count/aggregate result typing. Options-specific type/context checks must retain the options-clause bind separately from the flattened bind list; dynamic API validation must distinguish map keys from Apex variables. Database.QueryOptions declarations remain apex-ls#595. No changes outside apex-parser and no analyzer reproduction claimed.

@nawforce
nawforce marked this pull request as draft October 1, 2026 21:08
@kjonescertinia
kjonescertinia marked this pull request as ready for review October 2, 2026 08:54
@kjonescertinia
kjonescertinia merged commit ff7242f into main Oct 2, 2026
1 check passed
@kjonescertinia
kjonescertinia deleted the ao/apex-parser-3/set-options branch October 2, 2026 09:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support documented SOQL SET OPTIONS grammar and query-options binds

2 participants