Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] ppl #2094

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4080bfb
introduce pipeline proto changes
wu-hui Jun 6, 2024
608a75e
Add expressions, stages, and pipeline
wu-hui Jun 12, 2024
25ee91a
can run pipelines
wu-hui Jul 25, 2024
9ad2614
pipeline impl
wu-hui Jul 30, 2024
a514c65
Fix routing headers
wu-hui Aug 22, 2024
e957017
Basic initial converter support
wu-hui Aug 22, 2024
50f061b
Converter cleanup
wu-hui Aug 26, 2024
5947337
Address some feedbacks and add more nested field test.
wu-hui Aug 26, 2024
84e5eab
License header and tests fix
wu-hui Aug 26, 2024
eff4589
License header and tests fix
wu-hui Aug 26, 2024
0dd8b09
Merge remote-tracking branch 'origin/wuandy/PplPP' into wuandy/PplPP
wu-hui Aug 29, 2024
a3e62b5
Addressing comments.
wu-hui Sep 3, 2024
997c6c5
DTS + some other fixes.
wu-hui Sep 3, 2024
f0fdad5
FindNearest update
wu-hui Sep 5, 2024
f0ba8da
pipeline and stage dts fix done. expr to go.
wu-hui Sep 10, 2024
38b3981
fixing expression.ts type decl
wu-hui Sep 11, 2024
3aa8edd
length to strLength
wu-hui Sep 11, 2024
c97ed97
remove __path__ hack
wu-hui Sep 12, 2024
9116488
resync with expressions catelog
wu-hui Sep 25, 2024
670a124
comment out bit operations
wu-hui Sep 25, 2024
773bcd7
more syncs
wu-hui Sep 25, 2024
c22a2db
Fix rest connection by correct url endpoint.
wu-hui Oct 1, 2024
a0fb269
documentation fix
wu-hui Oct 1, 2024
b43de57
Fix system tests build error by not using `instanceof firestore.Expr`…
wu-hui Oct 1, 2024
1d9c585
remove __path__
wu-hui Oct 2, 2024
d9194b7
add reference test
wu-hui Oct 3, 2024
091ddf0
added transaction support.
wu-hui Oct 4, 2024
14b67dd
Add comments
wu-hui Oct 4, 2024
0c04b48
add remove_fields support
wu-hui Oct 24, 2024
91bd76e
add d.ts change for removeFields
wu-hui Oct 24, 2024
cb9d692
fix build
MarkDuckworth Nov 18, 2024
5db7307
Rename cond, *minimum, *maximum, eqAny, and notEqAny. New tests. Impl…
MarkDuckworth Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@ harassment or threats to anyone's safety, we may take action without notice.

This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
2 changes: 2 additions & 0 deletions dev/conformance/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ function normalizeTimestamp(obj: {[key: string]: {}}) {
if (fieldNames.includes(key) && typeof obj[key] === 'string') {
obj[key] = convertTimestamp(obj[key] as string);
} else if (typeof obj[key] === 'object') {
// @ts-ignore
normalizeTimestamp(obj[key]);
}
}
Expand Down Expand Up @@ -576,6 +577,7 @@ function normalizeInt32Value(obj: {[key: string]: {}}, parent = '') {
value: obj[key],
};
} else if (typeof obj[key] === 'object') {
// @ts-ignore
normalizeInt32Value(obj[key], key);
}
}
Expand Down
404 changes: 403 additions & 1 deletion dev/protos/firestore_v1_proto_api.d.ts

Large diffs are not rendered by default.

1,343 changes: 1,163 additions & 180 deletions dev/protos/firestore_v1_proto_api.js

Large diffs are not rendered by default.

114 changes: 114 additions & 0 deletions dev/protos/google/firestore/v1/document.proto
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,50 @@ message Value {

// A map value.
MapValue map_value = 6;


// Value which references a field.
//
// This is considered relative (vs absolute) since it only refers to a field
// and not a field within a particular document.
//
// **Requires:**
//
// * Must follow [field reference][FieldReference.field_path] limitations.
//
// * Not allowed to be used when writing documents.
//
// (-- NOTE(batchik): long term, there is no reason this type should not be
// allowed to be used on the write path. --)
string field_reference_value = 19;

// A value that represents an unevaluated expression.
//
// **Requires:**
//
// * Not allowed to be used when writing documents.
//
// (-- NOTE(batchik): similar to above, there is no reason to not allow
// storing expressions into the database, just no plan to support in
// the near term.
//
// This would actually be an interesting way to represent user-defined
// functions or more expressive rules-based systems. --)
Function function_value = 20;

// A value that represents an unevaluated pipeline.
//
// **Requires:**
//
// * Not allowed to be used when writing documents.
//
// (-- NOTE(batchik): similar to above, there is no reason to not allow
// storing expressions into the database, just no plan to support in
// the near term.
//
// This would actually be an interesting way to represent user-defined
// functions or more expressive rules-based systems. --)
Pipeline pipeline_value = 21;
}
}

Expand All @@ -147,3 +191,73 @@ message MapValue {
// not exceed 1,500 bytes and cannot be empty.
map<string, Value> fields = 1;
}

// Represents an unevaluated scalar expression.
//
// For example, the expression `like(user_name, "%alice%")` is represented as:
//
// ```
// name: "like"
// args { field_reference: "user_name" }
// args { string_value: "%alice%" }
// ```
//
// (-- api-linter: core::0123::resource-annotation=disabled
// aip.dev/not-precedent: this is not a One Platform API resource. --)
message Function {
// The name of the function to evaluate.
//
// **Requires:**
//
// * must be in snake case (lower case with underscore separator).
//
string name = 1;

// Ordered list of arguments the given function expects.
repeated Value args = 2;

// Optional named arguments that certain functions may support.
map<string, Value> options = 3;
}

// A Firestore query represented as an ordered list of operations / stages.
message Pipeline {
// A single operation within a pipeline.
//
// A stage is made up of a unique name, and a list of arguments. The exact
// number of arguments & types is dependent on the stage type.
//
// To give an example, the stage `filter(state = "MD")` would be encoded as:
//
// ```
// name: "filter"
// args {
// function_value {
// name: "eq"
// args { field_reference_value: "state" }
// args { string_value: "MD" }
// }
// }
// ```
//
// See public documentation for the full list.
message Stage {
// The name of the stage to evaluate.
//
// **Requires:**
//
// * must be in snake case (lower case with underscore separator).
//
string name = 1;

// Ordered list of arguments the given stage expects.
repeated Value args = 2;

// Optional named arguments that certain functions may support.
map<string, Value> options = 3;
}

// Ordered list of stages to evaluate.
repeated Stage stages = 1;
}

86 changes: 86 additions & 0 deletions dev/protos/google/firestore/v1/firestore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import "google/api/field_behavior.proto";
import "google/firestore/v1/aggregation_result.proto";
import "google/firestore/v1/common.proto";
import "google/firestore/v1/document.proto";
import "google/firestore/v1/pipeline.proto";
import "google/firestore/v1/query.proto";
import "google/firestore/v1/query_profile.proto";
import "google/firestore/v1/write.proto";
Expand Down Expand Up @@ -140,6 +141,15 @@ service Firestore {
};
}

// Executes a pipeline query.
rpc ExecutePipeline(ExecutePipelineRequest)
returns (stream ExecutePipelineResponse) {
option (google.api.http) = {
post: "/v1/{database=projects/*/databases/*}/documents:executePipeline"
body: "*"
};
}

// Runs an aggregation query.
//
// Rather than producing [Document][google.firestore.v1.Document] results like
Expand Down Expand Up @@ -624,6 +634,82 @@ message RunQueryResponse {
ExplainMetrics explain_metrics = 11;
}

// The request for [Firestore.ExecutePipeline][].
message ExecutePipelineRequest {
// Database identifier, in the form `projects/{project}/databases/{database}`.
string database = 1 [
(google.api.field_behavior) = REQUIRED
];

oneof pipeline_type {
// A pipelined operation.
StructuredPipeline structured_pipeline = 2;
}

// Optional consistency arguments, defaults to strong consistency.
oneof consistency_selector {
// Run the query within an already active transaction.
//
// The value here is the opaque transaction ID to execute the query in.
bytes transaction = 5;

// Execute the pipeline in a new transaction.
//
// The identifier of the newly created transaction will be returned in the
// first response on the stream. This defaults to a read-only transaction.
TransactionOptions new_transaction = 6;

// Execute the pipeline in a snapshot transaction at the given time.
//
// This must be a microsecond precision timestamp within the past one hour,
// or if Point-in-Time Recovery is enabled, can additionally be a whole
// minute timestamp within the past 7 days.
google.protobuf.Timestamp read_time = 7;
}

// Explain / analyze options for the pipeline.
// ExplainOptions explain_options = 8 [(google.api.field_behavior) = OPTIONAL];
}

// The response for [Firestore.Execute][].
message ExecutePipelineResponse {
// Newly created transaction identifier.
//
// This field is only specified on the first response from the server when
// the request specified [ExecuteRequest.new_transaction][].
bytes transaction = 1;

// An ordered batch of results returned executing a pipeline.
//
// The batch size is variable, and can even be zero for when only a partial
// progress message is returned.
//
// The fields present in the returned documents are only those that were
// explicitly requested in the pipeline, this include those like
// [`__name__`][Document.name] & [`__update_time__`][Document.update_time].
// This is explicitly a divergence from `Firestore.RunQuery` /
// `Firestore.GetDocument` RPCs which always return such fields even when they
// are not specified in the [`mask`][DocumentMask].
repeated Document results = 2;

// The time at which the document(s) were read.
//
// This may be monotonically increasing; in this case, the previous documents
// in the result stream are guaranteed not to have changed between their
// `execution_time` and this one.
//
// If the query returns no results, a response with `execution_time` and no
// `results` will be sent, and this represents the time at which the operation
// was run.
google.protobuf.Timestamp execution_time = 3;

// Query explain metrics.
//
// Set on the last response when [ExecutePipelineRequest.explain_options][]
// was specified on the request.
// ExplainMetrics explain_metrics = 4;
}

// The request for
// [Firestore.RunAggregationQuery][google.firestore.v1.Firestore.RunAggregationQuery].
message RunAggregationQueryRequest {
Expand Down
41 changes: 41 additions & 0 deletions dev/protos/google/firestore/v1/pipeline.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*!
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

syntax = "proto3";
package google.firestore.v1;
import "google/firestore/v1/document.proto";
option csharp_namespace = "Google.Cloud.Firestore.V1";
option php_namespace = "Google\\Cloud\\Firestore\\V1";
option ruby_package = "Google::Cloud::Firestore::V1";
option java_multiple_files = true;
option java_package = "com.google.firestore.v1";
option java_outer_classname = "PipelineProto";
option objc_class_prefix = "GCFS";
// A Firestore query represented as an ordered list of operations / stages.
//
// This is considered the top-level function which plans & executes a query.
// It is logically equivalent to `query(stages, options)`, but prevents the
// client from having to build a function wrapper.
message StructuredPipeline {
// The pipeline query to execute.
Pipeline pipeline = 1;
// Optional query-level arguments.
//
// (-- Think query statement hints. --)
//
// (-- TODO(batchik): define the api contract of using an unsupported hint --)
map<string, Value> options = 2;
}
Loading