Skip to content

feat(firestore): add DML stages, literals source, and atomic execution option to iOS SDK pipelines - #16500

Open
wu-hui wants to merge 2 commits into
firebase:mainfrom
wu-hui:feat-ios-pipeline-dml
Open

feat(firestore): add DML stages, literals source, and atomic execution option to iOS SDK pipelines#16500
wu-hui wants to merge 2 commits into
firebase:mainfrom
wu-hui:feat-ios-pipeline-dml

Conversation

@wu-hui

@wu-hui wu-hui commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds complete DML stages (DeleteStage, UpdateStage, InsertStage, UpsertStage), Literals source (LiteralsSourceStage), and atomic execution option (Pipeline.ExecuteOptions) to the iOS SDK (firebase-ios-sdk) Firestore Pipelines subsystem across the 3-layer architecture (C++ Core, Objective-C++ Bridge, Swift Public API).

Key Changes

  • Layer 3 — C++ Core (Firestore/core/src/api/ & remote/):
    • Implemented DeleteStage, UpdateStage, InsertStage, UpsertStage, and LiteralsSource classes in stages.h / stages.cc.
    • Added atomic execution flag support to Pipeline in pipeline.h / pipeline.cc and configured transaction options (new_transaction + auto_commit_transaction) in remote_objc_bridge.cc.
  • Layer 2 — Objective-C++ Bridge (Firestore/Source/API/):
    • Declared FIR*StageBridge classes in FIRPipelineBridge.h and implemented in FIRPipelineBridge.mm.
    • Updated FIRPipelineBridge initializer to pass atomic execution flag down to C++ Core.
  • Layer 1 — Swift Public API (Firestore/Swift/Source/):
    • Added Swift Stage class definitions in Stages.swift.
    • Added literals(...) entry point methods to PipelineSource.swift.
    • Added delete(), update(...), insert(...), upsert(...), and Pipeline.ExecuteOptions to Pipeline.swift.
  • Verification & Integration Test Suite (Firestore/Swift/Tests/Integration/):
    • Implemented full 11-test scenario suite in PipelineDmlTests.swift matching Web, Node, and Android test coverage.

Buganizer Ticket

Fixes http://b/545234002 (under umbrella http://b/500350942)

@gemini-code-assist

Copy link
Copy Markdown
Contributor
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

…n option to iOS SDK pipelines

BUG=b/545234002
TAG=agy
@wu-hui
wu-hui force-pushed the feat-ios-pipeline-dml branch from 7d36a1b to 54f611c Compare August 13, 2026 11:54
@wu-hui

wu-hui commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Quoting review comment from @ncooke3 on prototype PR #15801 (#15801 (comment)) for tracking on this PR:


  1. Purpose of returns: What use case does returns: solve? How do the different options affect the resulting Pipeline?

  2. Prefer concrete defaults
    For rawOptions, it looks like we immediately coalesce to [:] internally. For transactional, does the underlying bridge treat an omitted key differently than an explicit false? If not, defaulting to false and [:] reduces the number of states and is more idiomatic in Swift.

  3. Similar enums: The added enums share the same cases and raw values. Could we consolidate these into a single enum (e.g., DMLReturnMode) to reduce boilerplate? Additional configuration could be done via associated types.

  4. Ignored parameters in UpsertStage and InsertStage: Two of the three added subclasses of RawStage accept parameters (like collection and transformations) but completely ignore them in the super.init call. Is this subclassing pattern the right mechanism to differentiate these stages?

  5. API Consistency for collection: Why is collection an optional parameter for upsert but non-optional for insert? If we can't standardize the two, then clarifying in the docstring may be worth doing.

  6. Additional docstring examples: The existing methods in have nice code block examples showing how they are used. Could the new API also get similar examples, especially showing any of their unique params, like transformations and conflictResolution.


Context & Implementation Details in this PR (#16500):

  1. returns: & Return Enums Removed: The Firestore backend proto (google.firestore.v1.Pipeline.Stage) does not define a returns option for DML stages. Write observability was deprioritized in design reviews, so returns: and all associated enums (DeleteReturn, UpsertReturn, InsertReturn) have been removed across all SDKs.
  2. transactional: Moved to Pipeline.ExecuteOptions(atomic:): On the wire (ExecutePipelineRequest), transactions are request-level (new_transaction read-write + auto_commit_transaction = true), not per-stage. We removed transactional from individual stage methods and introduced Pipeline.ExecuteOptions(atomic: Bool = false) on pipeline.execute(options:).
  3. conflictResolution: Removed: DML semantics are modeled by distinct primitive stages (insert fails if document exists; update modifies in-place and fails if missing; upsert creates or merges). The backend proto does not support a conflictResolution option.
  4. Dedicated Stage Classes & C++ Core Bridge: Mock RawStage subclassing has been replaced with concrete Stage conformances (DeleteStage, UpdateStage, InsertStage, UpsertStage, LiteralsSourceStage) backed by dedicated Objective-C++ bridge classes (FIRPipelineBridge.mm) and C++ Core models (stages.h / stages.cc).
  5. collectionPath Optionality in upsert vs insert:
    • upsert: Optional (nil = in-place upsert on current pipeline stream; non-nil = target collection upsert).
    • insert: Required because it creates new documents from an incoming stream/literals into a designated destination collection (in-place insert on an existing collection query stream is semantically invalid).
  6. Docstrings & Examples: Added comprehensive integration test suites in PipelineDmlTests.swift covering all proposal code samples (1a through 5d) from go/firestore-dml-sdk-api.

@wu-hui
wu-hui force-pushed the feat-ios-pipeline-dml branch 2 times, most recently from 92283e7 to 73c1651 Compare August 19, 2026 20:02
…ngs to iOS Pipeline DML

- Default execute(options:) to concrete .init() and pass options.atomic directly
- Add rich Swift docstrings with code examples to execute(options:), delete(), update(), insert(), and upsert() in Pipeline.swift
- Explicitly note in docstrings why collectionPath is required for insert() and optional for upsert()
- Add rich Swift docstrings with code examples to literals() array and variadic overloads in PipelineSource.swift

BUG=b/545234002
TAG=agy
@wu-hui
wu-hui force-pushed the feat-ios-pipeline-dml branch from 73c1651 to b72add6 Compare August 19, 2026 20:03
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.

1 participant