Skip to content

feat(firestore): support insert, upsert, and literals stages in pipelines - #10200

Open
wu-hui wants to merge 13 commits into
mainfrom
feat-insert-upsert
Open

feat(firestore): support insert, upsert, and literals stages in pipelines#10200
wu-hui wants to merge 13 commits into
mainfrom
feat-insert-upsert

Conversation

@wu-hui

@wu-hui wu-hui commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Implements Insert, Upsert, and LiteralsSource pipeline stages and autoCommitTransaction transaction proto serialization.

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83

@wu-hui
wu-hui requested review from a team as code owners July 22, 2026 16:13
@changeset-bot

changeset-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1d4185b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces new DML pipeline stages (delete, update, insert, upsert) and a new literals source stage to Firestore pipelines, along with support for atomic execution via PipelineExecuteOptions. Feedback focuses on marking the literals method as @beta to resolve API extractor warnings, restoring the detailed documentation for execute(), and refactoring duplicated collection path normalization logic in the Insert and Upsert constructors.

Comment on lines +247 to +262
* Set the pipeline's source to in-memory literal document objects.
*
* @param document - A document object (key-value map).
* @param additionalDocuments - Optional additional document objects.
*/
literals(
document: Record<string, unknown>,
...additionalDocuments: Array<Record<string, unknown>>
): PipelineType;

/**
* Set the pipeline's source to in-memory literal document objects with options.
*
* @param options - Options containing the documents array.
*/
literals(options: LiteralsStageOptions): PipelineType;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The new literals method and its overloads should be marked as @beta to be consistent with other new pipeline features like insert and upsert. This will also resolve the ae-incompatible-release-tags warning in the generated API report.

  /**
   * @beta
   * Set the pipeline's source to in-memory literal document objects.
   *
   * @param document - A document object (key-value map).
   * @param additionalDocuments - Optional additional document objects.
   */
  literals(
    document: Record<string, unknown>,
    ...additionalDocuments: Array<Record<string, unknown>>
  ): PipelineType;

  /**
   * @beta
   * Set the pipeline's source to in-memory literal document objects with options.
   *
   * @param options - Options containing the documents array.
   */
  literals(options: LiteralsStageOptions): PipelineType;

Comment on lines 51 to 56
/**
* Executes this pipeline and returns a Promise to represent the asynchronous operation.
*
* The returned Promise can be used to track the progress of the pipeline execution
* and retrieve the results (or handle any errors) asynchronously.
*
* The pipeline results are returned as a {@link @firebase/firestore/pipelines#PipelineSnapshot} that contains
* a list of {@link @firebase/firestore/pipelines#PipelineResult} objects. Each {@link @firebase/firestore/pipelines#PipelineResult} typically
* represents a single key/value map that has passed through all the
* stages of the pipeline, however this might differ depending on the stages involved in the
* pipeline. For example:
*
* <ul>
* <li>If there are no stages or only transformation stages, each {@link @firebase/firestore/pipelines#PipelineResult}
* represents a single document.</li>
* <li>If there is an aggregation, only a single {@link @firebase/firestore/pipelines#PipelineResult} is returned,
* representing the aggregated results over the entire dataset .</li>
* <li>If there is an aggregation stage with grouping, each {@link @firebase/firestore/pipelines#PipelineResult} represents a
* distinct group and its associated aggregated values.</li>
* </ul>
*
* @example
* ```typescript
* const snapshot: PipelineSnapshot = await execute(firestore.pipeline().collection("books")
* .where(gt(field("rating"), 4.5))
* .select("title", "author", "rating"));
*
* const results: PipelineResults = snapshot.results;
* ```
*
* @param pipeline - The pipeline to execute.
* @returns A Promise representing the asynchronous pipeline execution.
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The detailed documentation for the execute() function has been removed as part of adding the new overload. This documentation was very helpful for users to understand what to expect from the pipeline execution results. It would be beneficial to restore it, perhaps on the first overload or as a general comment for the function.

Comment on lines +1050 to +1053
this.collectionPath = typeof collection === 'string' ? collection : collection.path;
if (!this.collectionPath.startsWith('/')) {
this.collectionPath = '/' + this.collectionPath;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for normalizing the collection path is duplicated in the Insert and Upsert stage constructors (lines 1109-1112). This could be extracted into a shared private helper function to reduce code duplication and improve maintainability.

@wu-hui
wu-hui force-pushed the feat-insert-upsert branch from 66d2bc5 to ce1aa81 Compare July 22, 2026 16:40
wu-hui added 13 commits July 22, 2026 16:47
…age.ts

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
…age.ts

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
…rs in stage.ts

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
…ion tests

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
Added InsertStageOptions and UpsertStageOptions types, Insert and Upsert stage classes, and fluent .insert() and .upsert() methods on Pipeline. Also updated ExecutePipelineRequest serialization to correctly pass newTransaction when atomic execution is requested.

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
Implemented LiteralsStageOptions, LiteralsSource stage, and .literals() method overloads (vararg and options object) on PipelineSource. Enables in-memory document pipelines and non-transactional DML writes when using literal document sources.

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
…st transaction fields

Added RequestOptions to common.proto and auto_commit_transaction/request_options fields to ExecutePipelineRequest in firestore.proto. Regenerated protos.json via compile.sh and updated firestore_proto_api.ts interfaces.

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
…nd tests

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
… files

TAG=agy
CONV=74d82eb4-f542-4abb-af06-5c096595ec83
@wu-hui
wu-hui force-pushed the feat-insert-upsert branch from ce1aa81 to 1d4185b Compare July 22, 2026 17:02
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