risingwave_pb/
stream_plan.rs

1// This file is @generated by prost-build.
2#[derive(prost_helpers::AnyPB)]
3#[derive(Clone, PartialEq, ::prost::Message)]
4pub struct Dispatchers {
5    #[prost(message, repeated, tag = "1")]
6    pub dispatchers: ::prost::alloc::vec::Vec<Dispatcher>,
7}
8#[derive(prost_helpers::AnyPB)]
9#[derive(Clone, PartialEq, ::prost::Message)]
10pub struct UpstreamSinkInfo {
11    #[prost(uint32, tag = "1", wrapper = "crate::id::FragmentId")]
12    pub upstream_fragment_id: crate::id::FragmentId,
13    #[prost(message, repeated, tag = "2")]
14    pub sink_output_schema: ::prost::alloc::vec::Vec<super::plan_common::Field>,
15    #[prost(message, repeated, tag = "3")]
16    pub project_exprs: ::prost::alloc::vec::Vec<super::expr::ExprNode>,
17}
18#[derive(prost_helpers::AnyPB)]
19#[derive(Clone, PartialEq, ::prost::Message)]
20pub struct AddMutation {
21    /// New dispatchers for each actor.
22    #[prost(map = "uint32, message", tag = "1", wrapper = "crate::id::ActorId")]
23    pub actor_dispatchers: ::std::collections::HashMap<crate::id::ActorId, Dispatchers>,
24    /// All actors to be added (to the main connected component of the graph) in this update.
25    #[prost(uint32, repeated, tag = "3", wrapper = "crate::id::ActorId")]
26    pub added_actors: ::prost::alloc::vec::Vec<crate::id::ActorId>,
27    /// We may embed a source change split mutation here.
28    /// `Source` and `SourceBackfill` are handled together here.
29    /// TODO: we may allow multiple mutations in a single barrier.
30    #[prost(map = "uint32, message", tag = "2", wrapper = "crate::id::ActorId")]
31    pub actor_splits: ::std::collections::HashMap<
32        crate::id::ActorId,
33        super::source::ConnectorSplits,
34    >,
35    /// We may embed a pause mutation here.
36    /// TODO: we may allow multiple mutations in a single barrier.
37    #[prost(bool, tag = "4")]
38    pub pause: bool,
39    #[prost(message, repeated, tag = "5")]
40    pub subscriptions_to_add: ::prost::alloc::vec::Vec<SubscriptionUpstreamInfo>,
41    /// nodes which should be paused initially.
42    #[prost(uint32, repeated, tag = "6", wrapper = "crate::id::FragmentId")]
43    pub backfill_nodes_to_pause: ::prost::alloc::vec::Vec<crate::id::FragmentId>,
44    /// CDC table snapshot splits
45    #[prost(message, optional, tag = "7")]
46    pub actor_cdc_table_snapshot_splits: ::core::option::Option<
47        super::source::CdcTableSnapshotSplitsWithGeneration,
48    >,
49    /// Use downstream_fragment_id as keys.
50    #[prost(map = "uint32, message", tag = "8", wrapper = "crate::id::FragmentId")]
51    pub new_upstream_sinks: ::std::collections::HashMap<
52        crate::id::FragmentId,
53        add_mutation::NewUpstreamSink,
54    >,
55}
56/// Nested message and enum types in `AddMutation`.
57pub mod add_mutation {
58    #[derive(prost_helpers::AnyPB)]
59    #[derive(Clone, PartialEq, ::prost::Message)]
60    pub struct NewUpstreamSink {
61        #[prost(message, optional, tag = "1")]
62        pub info: ::core::option::Option<super::UpstreamSinkInfo>,
63        #[prost(message, repeated, tag = "2")]
64        pub upstream_actors: ::prost::alloc::vec::Vec<super::super::common::ActorInfo>,
65    }
66}
67#[derive(prost_helpers::AnyPB)]
68#[derive(Clone, PartialEq, ::prost::Message)]
69pub struct StopMutation {
70    #[prost(uint32, repeated, tag = "1", wrapper = "crate::id::ActorId")]
71    pub actors: ::prost::alloc::vec::Vec<crate::id::ActorId>,
72    /// Only sink-fragment in the sink job is recorded.
73    #[prost(uint32, repeated, tag = "2", wrapper = "crate::id::FragmentId")]
74    pub dropped_sink_fragments: ::prost::alloc::vec::Vec<crate::id::FragmentId>,
75}
76#[derive(prost_helpers::AnyPB)]
77#[derive(Clone, PartialEq, ::prost::Message)]
78pub struct UpdateMutation {
79    /// Dispatcher updates.
80    #[prost(message, repeated, tag = "1")]
81    pub dispatcher_update: ::prost::alloc::vec::Vec<update_mutation::DispatcherUpdate>,
82    /// Merge updates.
83    #[prost(message, repeated, tag = "2")]
84    pub merge_update: ::prost::alloc::vec::Vec<update_mutation::MergeUpdate>,
85    /// Vnode bitmap updates for each actor.
86    #[prost(map = "uint32, message", tag = "3", wrapper = "crate::id::ActorId")]
87    pub actor_vnode_bitmap_update: ::std::collections::HashMap<
88        crate::id::ActorId,
89        super::common::Buffer,
90    >,
91    /// All actors to be dropped in this update.
92    #[prost(uint32, repeated, tag = "4", wrapper = "crate::id::ActorId")]
93    pub dropped_actors: ::prost::alloc::vec::Vec<crate::id::ActorId>,
94    /// Source updates.
95    /// `Source` and `SourceBackfill` are handled together here.
96    #[prost(map = "uint32, message", tag = "5", wrapper = "crate::id::ActorId")]
97    pub actor_splits: ::std::collections::HashMap<
98        crate::id::ActorId,
99        super::source::ConnectorSplits,
100    >,
101    /// When modifying the Materialized View, we need to recreate the Dispatcher from the old upstream to the new TableFragment.
102    /// Consistent with the semantics in AddMutation.
103    #[prost(map = "uint32, message", tag = "6", wrapper = "crate::id::ActorId")]
104    pub actor_new_dispatchers: ::std::collections::HashMap<
105        crate::id::ActorId,
106        Dispatchers,
107    >,
108    /// CDC table snapshot splits
109    #[prost(message, optional, tag = "7")]
110    pub actor_cdc_table_snapshot_splits: ::core::option::Option<
111        super::source::CdcTableSnapshotSplitsWithGeneration,
112    >,
113    #[prost(map = "uint32, message", tag = "8")]
114    pub sink_schema_change: ::std::collections::HashMap<u32, SinkSchemaChange>,
115    #[prost(message, repeated, tag = "9")]
116    pub subscriptions_to_drop: ::prost::alloc::vec::Vec<SubscriptionUpstreamInfo>,
117}
118/// Nested message and enum types in `UpdateMutation`.
119pub mod update_mutation {
120    #[derive(prost_helpers::AnyPB)]
121    #[derive(Clone, PartialEq, ::prost::Message)]
122    pub struct DispatcherUpdate {
123        /// Dispatcher can be uniquely identified by a combination of actor id and dispatcher id.
124        #[prost(uint32, tag = "1", wrapper = "crate::id::ActorId")]
125        pub actor_id: crate::id::ActorId,
126        #[prost(uint32, tag = "2", wrapper = "crate::id::FragmentId")]
127        pub dispatcher_id: crate::id::FragmentId,
128        /// The hash mapping for consistent hash.
129        /// For dispatcher types other than HASH, this is ignored.
130        #[prost(message, optional, tag = "3")]
131        pub hash_mapping: ::core::option::Option<super::ActorMapping>,
132        /// Added downstream actors.
133        #[prost(uint32, repeated, tag = "4", wrapper = "crate::id::ActorId")]
134        pub added_downstream_actor_id: ::prost::alloc::vec::Vec<crate::id::ActorId>,
135        /// Removed downstream actors.
136        #[prost(uint32, repeated, tag = "5", wrapper = "crate::id::ActorId")]
137        pub removed_downstream_actor_id: ::prost::alloc::vec::Vec<crate::id::ActorId>,
138    }
139    #[derive(prost_helpers::AnyPB)]
140    #[derive(Clone, PartialEq, ::prost::Message)]
141    pub struct MergeUpdate {
142        /// Merge executor can be uniquely identified by a combination of actor id and upstream fragment id.
143        #[prost(uint32, tag = "1", wrapper = "crate::id::ActorId")]
144        pub actor_id: crate::id::ActorId,
145        #[prost(uint32, tag = "2", wrapper = "crate::id::FragmentId")]
146        pub upstream_fragment_id: crate::id::FragmentId,
147        /// - For scaling, this is always `None`.
148        /// - For plan change, the upstream fragment will be changed to a new one, and this will be `Some`.
149        ///    In this case, all the upstream actors should be removed and replaced by the `new` ones.
150        #[prost(uint32, optional, tag = "5", wrapper = "crate::id::FragmentId")]
151        pub new_upstream_fragment_id: ::core::option::Option<crate::id::FragmentId>,
152        /// Added upstream actors.
153        #[prost(message, repeated, tag = "3")]
154        pub added_upstream_actors: ::prost::alloc::vec::Vec<
155            super::super::common::ActorInfo,
156        >,
157        /// Removed upstream actors.
158        /// Note: this is empty for replace job.
159        #[prost(uint32, repeated, tag = "4", wrapper = "crate::id::ActorId")]
160        pub removed_upstream_actor_id: ::prost::alloc::vec::Vec<crate::id::ActorId>,
161    }
162}
163#[derive(prost_helpers::AnyPB)]
164#[derive(Clone, PartialEq, ::prost::Message)]
165pub struct SourceChangeSplitMutation {
166    /// `Source` and `SourceBackfill` are handled together here.
167    #[prost(map = "uint32, message", tag = "2", wrapper = "crate::id::ActorId")]
168    pub actor_splits: ::std::collections::HashMap<
169        crate::id::ActorId,
170        super::source::ConnectorSplits,
171    >,
172}
173#[derive(prost_helpers::AnyPB)]
174#[derive(Clone, Copy, PartialEq, ::prost::Message)]
175pub struct PauseMutation {}
176#[derive(prost_helpers::AnyPB)]
177#[derive(Clone, Copy, PartialEq, ::prost::Message)]
178pub struct ResumeMutation {}
179#[derive(prost_helpers::AnyPB)]
180#[derive(Clone, PartialEq, ::prost::Message)]
181pub struct ThrottleMutation {
182    #[prost(map = "uint32, message", tag = "1", wrapper = "crate::id::FragmentId")]
183    pub fragment_throttle: ::std::collections::HashMap<
184        crate::id::FragmentId,
185        throttle_mutation::ThrottleConfig,
186    >,
187}
188/// Nested message and enum types in `ThrottleMutation`.
189pub mod throttle_mutation {
190    #[derive(prost_helpers::AnyPB)]
191    #[derive(Clone, Copy, PartialEq, ::prost::Message)]
192    pub struct ThrottleConfig {
193        #[prost(uint32, optional, tag = "1")]
194        pub rate_limit: ::core::option::Option<u32>,
195        #[prost(enumeration = "super::super::common::ThrottleType", tag = "2")]
196        pub throttle_type: i32,
197    }
198}
199#[derive(prost_helpers::AnyPB)]
200#[derive(Clone, Copy, PartialEq, ::prost::Message)]
201pub struct SubscriptionUpstreamInfo {
202    /// can either be subscription_id or table_id of creating TableFragments
203    #[prost(uint32, tag = "1", wrapper = "crate::id::SubscriberId")]
204    pub subscriber_id: crate::id::SubscriberId,
205    #[prost(uint32, tag = "2", wrapper = "crate::id::TableId")]
206    pub upstream_mv_table_id: crate::id::TableId,
207}
208#[derive(prost_helpers::AnyPB)]
209#[derive(Clone, PartialEq, ::prost::Message)]
210pub struct DropSubscriptionsMutation {
211    #[prost(message, repeated, tag = "1")]
212    pub info: ::prost::alloc::vec::Vec<SubscriptionUpstreamInfo>,
213}
214#[derive(prost_helpers::AnyPB)]
215#[derive(Clone, PartialEq, ::prost::Message)]
216pub struct ConnectorPropsChangeMutation {
217    #[prost(map = "uint32, message", tag = "1")]
218    pub connector_props_infos: ::std::collections::HashMap<
219        u32,
220        connector_props_change_mutation::ConnectorPropsInfo,
221    >,
222}
223/// Nested message and enum types in `ConnectorPropsChangeMutation`.
224pub mod connector_props_change_mutation {
225    #[derive(prost_helpers::AnyPB)]
226    #[derive(Clone, PartialEq, ::prost::Message)]
227    pub struct ConnectorPropsInfo {
228        #[prost(map = "string, string", tag = "1")]
229        pub connector_props_info: ::std::collections::HashMap<
230            ::prost::alloc::string::String,
231            ::prost::alloc::string::String,
232        >,
233    }
234}
235#[derive(prost_helpers::AnyPB)]
236#[derive(Clone, PartialEq, ::prost::Message)]
237pub struct StartFragmentBackfillMutation {
238    #[prost(uint32, repeated, tag = "1", wrapper = "crate::id::FragmentId")]
239    pub fragment_ids: ::prost::alloc::vec::Vec<crate::id::FragmentId>,
240}
241#[derive(prost_helpers::AnyPB)]
242#[derive(Clone, Copy, PartialEq, ::prost::Message)]
243pub struct RefreshStartMutation {
244    /// Table ID to start refresh operation.
245    #[prost(uint32, tag = "1", wrapper = "crate::id::TableId")]
246    pub table_id: crate::id::TableId,
247    /// Associated source ID for this refresh operation.
248    #[prost(uint32, tag = "2", wrapper = "crate::id::SourceId")]
249    pub associated_source_id: crate::id::SourceId,
250}
251#[derive(prost_helpers::AnyPB)]
252#[derive(Clone, Copy, PartialEq, ::prost::Message)]
253pub struct ListFinishMutation {
254    /// Associated source ID for this list operation.
255    #[prost(uint32, tag = "1", wrapper = "crate::id::SourceId")]
256    pub associated_source_id: crate::id::SourceId,
257}
258#[derive(prost_helpers::AnyPB)]
259#[derive(Clone, Copy, PartialEq, ::prost::Message)]
260pub struct LoadFinishMutation {
261    /// Associated source ID for this load operation.
262    #[prost(uint32, tag = "1", wrapper = "crate::id::SourceId")]
263    pub associated_source_id: crate::id::SourceId,
264}
265#[derive(prost_helpers::AnyPB)]
266#[derive(Clone, Copy, PartialEq, ::prost::Message)]
267pub struct ResetSourceMutation {
268    /// Source ID to reset
269    #[prost(uint32, tag = "1")]
270    pub source_id: u32,
271}
272#[derive(prost_helpers::AnyPB)]
273#[derive(Clone, PartialEq, ::prost::Message)]
274pub struct BarrierMutation {
275    #[prost(
276        oneof = "barrier_mutation::Mutation",
277        tags = "3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15, 16, 17, 18"
278    )]
279    pub mutation: ::core::option::Option<barrier_mutation::Mutation>,
280}
281/// Nested message and enum types in `BarrierMutation`.
282pub mod barrier_mutation {
283    #[derive(prost_helpers::AnyPB)]
284    #[derive(Clone, PartialEq, ::prost::Oneof)]
285    pub enum Mutation {
286        /// Add new dispatchers to some actors, used for creating materialized views.
287        #[prost(message, tag = "3")]
288        Add(super::AddMutation),
289        /// Stop a set of actors, used for dropping materialized views. Empty dispatchers will be
290        /// automatically removed.
291        #[prost(message, tag = "4")]
292        Stop(super::StopMutation),
293        /// Update outputs and hash mappings for some dispatchers, used for scaling and replace table.
294        #[prost(message, tag = "5")]
295        Update(super::UpdateMutation),
296        /// Change the split of some sources.
297        #[prost(message, tag = "6")]
298        Splits(super::SourceChangeSplitMutation),
299        /// Pause the dataflow of the whole streaming graph, only used for scaling.
300        #[prost(message, tag = "7")]
301        Pause(super::PauseMutation),
302        /// Resume the dataflow of the whole streaming graph, only used for scaling.
303        #[prost(message, tag = "8")]
304        Resume(super::ResumeMutation),
305        /// Alter the RateLimit of some specific executors
306        #[prost(message, tag = "10")]
307        Throttle(super::ThrottleMutation),
308        /// Drop subscription on mv
309        #[prost(message, tag = "12")]
310        DropSubscriptions(super::DropSubscriptionsMutation),
311        /// Alter sink/connector/source props
312        #[prost(message, tag = "13")]
313        ConnectorPropsChange(super::ConnectorPropsChangeMutation),
314        /// Start backfilling for specific fragments
315        /// This is separated from `ThrottleMutation::NO_RATE_LIMIT`.
316        /// This is because user may concurrently rate limit + use backfill order control.
317        /// If we use rate limit to pause / resume backfill fragments, if user manually
318        /// resumes some fragments, this will overwrite the backfill order configuration.
319        #[prost(message, tag = "14")]
320        StartFragmentBackfill(super::StartFragmentBackfillMutation),
321        /// Start refresh signal for refreshing tables
322        #[prost(message, tag = "15")]
323        RefreshStart(super::RefreshStartMutation),
324        /// Load finish signal for refreshing tables
325        #[prost(message, tag = "16")]
326        LoadFinish(super::LoadFinishMutation),
327        /// List finish signal for refreshing tables
328        #[prost(message, tag = "17")]
329        ListFinish(super::ListFinishMutation),
330        /// Reset CDC source offset to latest
331        #[prost(message, tag = "18")]
332        ResetSource(super::ResetSourceMutation),
333    }
334}
335#[derive(prost_helpers::AnyPB)]
336#[derive(Clone, PartialEq, ::prost::Message)]
337pub struct Barrier {
338    #[prost(message, optional, tag = "1")]
339    pub epoch: ::core::option::Option<super::data::Epoch>,
340    #[prost(message, optional, tag = "3")]
341    pub mutation: ::core::option::Option<BarrierMutation>,
342    /// Used for tracing.
343    #[prost(map = "string, string", tag = "2")]
344    pub tracing_context: ::std::collections::HashMap<
345        ::prost::alloc::string::String,
346        ::prost::alloc::string::String,
347    >,
348    /// The kind of the barrier.
349    #[prost(enumeration = "barrier::BarrierKind", tag = "9")]
350    pub kind: i32,
351}
352/// Nested message and enum types in `Barrier`.
353pub mod barrier {
354    #[derive(prost_helpers::AnyPB)]
355    #[derive(::enum_as_inner::EnumAsInner)]
356    #[derive(
357        Clone,
358        Copy,
359        Debug,
360        PartialEq,
361        Eq,
362        Hash,
363        PartialOrd,
364        Ord,
365        ::prost::Enumeration
366    )]
367    #[repr(i32)]
368    pub enum BarrierKind {
369        Unspecified = 0,
370        /// The first barrier after a fresh start or recovery.
371        /// There will be no data associated with the previous epoch of the barrier.
372        Initial = 1,
373        /// A normal barrier. Data should be flushed locally.
374        Barrier = 2,
375        /// A checkpoint barrier. Data should be synchorized to the shared storage.
376        Checkpoint = 3,
377    }
378    impl BarrierKind {
379        /// String value of the enum field names used in the ProtoBuf definition.
380        ///
381        /// The values are not transformed in any way and thus are considered stable
382        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
383        pub fn as_str_name(&self) -> &'static str {
384            match self {
385                Self::Unspecified => "BARRIER_KIND_UNSPECIFIED",
386                Self::Initial => "BARRIER_KIND_INITIAL",
387                Self::Barrier => "BARRIER_KIND_BARRIER",
388                Self::Checkpoint => "BARRIER_KIND_CHECKPOINT",
389            }
390        }
391        /// Creates an enum from field names used in the ProtoBuf definition.
392        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
393            match value {
394                "BARRIER_KIND_UNSPECIFIED" => Some(Self::Unspecified),
395                "BARRIER_KIND_INITIAL" => Some(Self::Initial),
396                "BARRIER_KIND_BARRIER" => Some(Self::Barrier),
397                "BARRIER_KIND_CHECKPOINT" => Some(Self::Checkpoint),
398                _ => None,
399            }
400        }
401    }
402}
403#[derive(prost_helpers::AnyPB)]
404#[derive(Clone, PartialEq, ::prost::Message)]
405pub struct Watermark {
406    /// The reference to the watermark column in the stream's schema.
407    #[prost(message, optional, tag = "1")]
408    pub column: ::core::option::Option<super::expr::InputRef>,
409    /// The watermark value, there will be no record having a greater value in the watermark column.
410    #[prost(message, optional, tag = "3")]
411    pub val: ::core::option::Option<super::data::Datum>,
412}
413#[derive(prost_helpers::AnyPB)]
414#[derive(Clone, PartialEq, ::prost::Message)]
415pub struct StreamMessage {
416    #[prost(oneof = "stream_message::StreamMessage", tags = "1, 2, 3")]
417    pub stream_message: ::core::option::Option<stream_message::StreamMessage>,
418}
419/// Nested message and enum types in `StreamMessage`.
420pub mod stream_message {
421    #[derive(prost_helpers::AnyPB)]
422    #[derive(Clone, PartialEq, ::prost::Oneof)]
423    pub enum StreamMessage {
424        #[prost(message, tag = "1")]
425        StreamChunk(super::super::data::StreamChunk),
426        #[prost(message, tag = "2")]
427        Barrier(super::Barrier),
428        #[prost(message, tag = "3")]
429        Watermark(super::Watermark),
430    }
431}
432#[derive(prost_helpers::AnyPB)]
433#[derive(Clone, PartialEq, ::prost::Message)]
434pub struct StreamMessageBatch {
435    #[prost(oneof = "stream_message_batch::StreamMessageBatch", tags = "1, 2, 3")]
436    pub stream_message_batch: ::core::option::Option<
437        stream_message_batch::StreamMessageBatch,
438    >,
439}
440/// Nested message and enum types in `StreamMessageBatch`.
441pub mod stream_message_batch {
442    #[derive(prost_helpers::AnyPB)]
443    #[derive(Clone, PartialEq, ::prost::Message)]
444    pub struct BarrierBatch {
445        #[prost(message, repeated, tag = "1")]
446        pub barriers: ::prost::alloc::vec::Vec<super::Barrier>,
447    }
448    #[derive(prost_helpers::AnyPB)]
449    #[derive(Clone, PartialEq, ::prost::Oneof)]
450    pub enum StreamMessageBatch {
451        #[prost(message, tag = "1")]
452        StreamChunk(super::super::data::StreamChunk),
453        #[prost(message, tag = "2")]
454        BarrierBatch(BarrierBatch),
455        #[prost(message, tag = "3")]
456        Watermark(super::Watermark),
457    }
458}
459/// Hash mapping for compute node. Stores mapping from virtual node to actor id.
460#[derive(prost_helpers::AnyPB)]
461#[derive(Clone, PartialEq, ::prost::Message)]
462pub struct ActorMapping {
463    #[prost(uint32, repeated, tag = "1")]
464    pub original_indices: ::prost::alloc::vec::Vec<u32>,
465    #[prost(uint32, repeated, tag = "2", wrapper = "crate::id::ActorId")]
466    pub data: ::prost::alloc::vec::Vec<crate::id::ActorId>,
467}
468#[derive(prost_helpers::AnyPB)]
469#[derive(Clone, PartialEq, ::prost::Message)]
470pub struct Columns {
471    #[prost(message, repeated, tag = "1")]
472    pub columns: ::prost::alloc::vec::Vec<super::plan_common::ColumnCatalog>,
473}
474#[derive(prost_helpers::AnyPB)]
475#[derive(Clone, PartialEq, ::prost::Message)]
476pub struct StreamSource {
477    #[prost(uint32, tag = "1", wrapper = "crate::id::SourceId")]
478    pub source_id: crate::id::SourceId,
479    #[prost(message, optional, tag = "2")]
480    pub state_table: ::core::option::Option<super::catalog::Table>,
481    #[prost(uint32, optional, tag = "3")]
482    pub row_id_index: ::core::option::Option<u32>,
483    #[prost(message, repeated, tag = "4")]
484    pub columns: ::prost::alloc::vec::Vec<super::plan_common::ColumnCatalog>,
485    #[prost(btree_map = "string, string", tag = "6")]
486    pub with_properties: ::prost::alloc::collections::BTreeMap<
487        ::prost::alloc::string::String,
488        ::prost::alloc::string::String,
489    >,
490    #[prost(message, optional, tag = "7")]
491    pub info: ::core::option::Option<super::catalog::StreamSourceInfo>,
492    #[prost(string, tag = "8")]
493    pub source_name: ::prost::alloc::string::String,
494    /// Source rate limit
495    #[prost(uint32, optional, tag = "9")]
496    pub rate_limit: ::core::option::Option<u32>,
497    #[prost(btree_map = "string, message", tag = "10")]
498    pub secret_refs: ::prost::alloc::collections::BTreeMap<
499        ::prost::alloc::string::String,
500        super::secret::SecretRef,
501    >,
502    /// Downstream columns are used by list node to know which columns are needed.
503    #[prost(message, optional, tag = "11")]
504    pub downstream_columns: ::core::option::Option<Columns>,
505    #[prost(message, optional, tag = "12")]
506    pub refresh_mode: ::core::option::Option<super::plan_common::SourceRefreshMode>,
507    #[prost(uint32, optional, tag = "13", wrapper = "crate::id::TableId")]
508    pub associated_table_id: ::core::option::Option<crate::id::TableId>,
509}
510/// copy contents from StreamSource to prevent compatibility issues in the future
511#[derive(prost_helpers::AnyPB)]
512#[derive(Clone, PartialEq, ::prost::Message)]
513pub struct StreamFsFetch {
514    #[prost(uint32, tag = "1", wrapper = "crate::id::SourceId")]
515    pub source_id: crate::id::SourceId,
516    #[prost(message, optional, tag = "2")]
517    pub state_table: ::core::option::Option<super::catalog::Table>,
518    #[prost(uint32, optional, tag = "3")]
519    pub row_id_index: ::core::option::Option<u32>,
520    #[prost(message, repeated, tag = "4")]
521    pub columns: ::prost::alloc::vec::Vec<super::plan_common::ColumnCatalog>,
522    #[prost(btree_map = "string, string", tag = "6")]
523    pub with_properties: ::prost::alloc::collections::BTreeMap<
524        ::prost::alloc::string::String,
525        ::prost::alloc::string::String,
526    >,
527    #[prost(message, optional, tag = "7")]
528    pub info: ::core::option::Option<super::catalog::StreamSourceInfo>,
529    #[prost(string, tag = "8")]
530    pub source_name: ::prost::alloc::string::String,
531    /// Source rate limit
532    #[prost(uint32, optional, tag = "9")]
533    pub rate_limit: ::core::option::Option<u32>,
534    #[prost(btree_map = "string, message", tag = "10")]
535    pub secret_refs: ::prost::alloc::collections::BTreeMap<
536        ::prost::alloc::string::String,
537        super::secret::SecretRef,
538    >,
539    #[prost(message, optional, tag = "11")]
540    pub refresh_mode: ::core::option::Option<super::plan_common::SourceRefreshMode>,
541    #[prost(uint32, optional, tag = "12", wrapper = "crate::id::TableId")]
542    pub associated_table_id: ::core::option::Option<crate::id::TableId>,
543}
544/// The executor only for receiving barrier from the meta service. It always resides in the leaves
545/// of the streaming graph.
546#[derive(prost_helpers::AnyPB)]
547#[derive(Clone, Copy, PartialEq, ::prost::Message)]
548pub struct BarrierRecvNode {}
549#[derive(prost_helpers::AnyPB)]
550#[derive(Clone, PartialEq, ::prost::Message)]
551pub struct SourceNode {
552    /// The source node can contain either a stream source or nothing. So here we extract all
553    /// information about stream source to a message, and here it will be an `Option` in Rust.
554    #[prost(message, optional, tag = "1")]
555    pub source_inner: ::core::option::Option<StreamSource>,
556}
557#[derive(prost_helpers::AnyPB)]
558#[derive(Clone, PartialEq, ::prost::Message)]
559pub struct StreamFsFetchNode {
560    #[prost(message, optional, tag = "1")]
561    pub node_inner: ::core::option::Option<StreamFsFetch>,
562}
563/// / It's input must be a `MergeNode`, which connects to the upstream source job.
564/// / See `StreamSourceScan::adhoc_to_stream_prost` for the plan.
565#[derive(prost_helpers::AnyPB)]
566#[derive(Clone, PartialEq, ::prost::Message)]
567pub struct SourceBackfillNode {
568    #[prost(uint32, tag = "1", wrapper = "crate::id::SourceId")]
569    pub upstream_source_id: crate::id::SourceId,
570    #[prost(uint32, optional, tag = "2")]
571    pub row_id_index: ::core::option::Option<u32>,
572    #[prost(message, repeated, tag = "3")]
573    pub columns: ::prost::alloc::vec::Vec<super::plan_common::ColumnCatalog>,
574    #[prost(message, optional, tag = "4")]
575    pub info: ::core::option::Option<super::catalog::StreamSourceInfo>,
576    #[prost(string, tag = "5")]
577    pub source_name: ::prost::alloc::string::String,
578    #[prost(btree_map = "string, string", tag = "6")]
579    pub with_properties: ::prost::alloc::collections::BTreeMap<
580        ::prost::alloc::string::String,
581        ::prost::alloc::string::String,
582    >,
583    /// Backfill rate limit
584    #[prost(uint32, optional, tag = "7")]
585    pub rate_limit: ::core::option::Option<u32>,
586    /// `| partition_id | backfill_progress |`
587    #[prost(message, optional, tag = "8")]
588    pub state_table: ::core::option::Option<super::catalog::Table>,
589    #[prost(btree_map = "string, message", tag = "9")]
590    pub secret_refs: ::prost::alloc::collections::BTreeMap<
591        ::prost::alloc::string::String,
592        super::secret::SecretRef,
593    >,
594}
595#[derive(prost_helpers::AnyPB)]
596#[derive(Clone, PartialEq, ::prost::Message)]
597pub struct SinkDesc {
598    #[prost(uint32, tag = "1", wrapper = "crate::id::SinkId")]
599    pub id: crate::id::SinkId,
600    #[prost(string, tag = "2")]
601    pub name: ::prost::alloc::string::String,
602    #[prost(string, tag = "3")]
603    pub definition: ::prost::alloc::string::String,
604    #[prost(message, repeated, tag = "5")]
605    pub plan_pk: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
606    #[prost(uint32, repeated, tag = "6")]
607    pub downstream_pk: ::prost::alloc::vec::Vec<u32>,
608    #[prost(uint32, repeated, tag = "7")]
609    pub distribution_key: ::prost::alloc::vec::Vec<u32>,
610    #[prost(btree_map = "string, string", tag = "8")]
611    pub properties: ::prost::alloc::collections::BTreeMap<
612        ::prost::alloc::string::String,
613        ::prost::alloc::string::String,
614    >,
615    /// to be deprecated
616    #[prost(enumeration = "super::catalog::SinkType", tag = "9")]
617    pub sink_type: i32,
618    #[prost(message, repeated, tag = "10")]
619    pub column_catalogs: ::prost::alloc::vec::Vec<super::plan_common::ColumnCatalog>,
620    #[prost(string, tag = "11")]
621    pub db_name: ::prost::alloc::string::String,
622    /// If the sink is from table or mv, this is name of the table/mv. Otherwise
623    /// it is the name of the sink itself.
624    #[prost(string, tag = "12")]
625    pub sink_from_name: ::prost::alloc::string::String,
626    #[prost(message, optional, tag = "13")]
627    pub format_desc: ::core::option::Option<super::catalog::SinkFormatDesc>,
628    #[prost(uint32, optional, tag = "14")]
629    pub target_table: ::core::option::Option<u32>,
630    #[prost(uint64, optional, tag = "15")]
631    pub extra_partition_col_idx: ::core::option::Option<u64>,
632    #[prost(btree_map = "string, message", tag = "16")]
633    pub secret_refs: ::prost::alloc::collections::BTreeMap<
634        ::prost::alloc::string::String,
635        super::secret::SecretRef,
636    >,
637    /// Backward-compatible replacement for `SINK_TYPE_FORCE_APPEND_ONLY`.
638    ///
639    /// Should not directly access this field. Use method `ignore_delete()` instead.
640    #[prost(bool, tag = "17")]
641    pub raw_ignore_delete: bool,
642}
643#[derive(prost_helpers::AnyPB)]
644#[derive(Clone, PartialEq, ::prost::Message)]
645pub struct SinkNode {
646    #[prost(message, optional, tag = "1")]
647    pub sink_desc: ::core::option::Option<SinkDesc>,
648    /// A sink with a kv log store should have a table.
649    #[prost(message, optional, tag = "2")]
650    pub table: ::core::option::Option<super::catalog::Table>,
651    #[prost(enumeration = "SinkLogStoreType", tag = "3")]
652    pub log_store_type: i32,
653    #[prost(uint32, optional, tag = "4")]
654    pub rate_limit: ::core::option::Option<u32>,
655}
656#[derive(prost_helpers::AnyPB)]
657#[derive(Clone, PartialEq, ::prost::Message)]
658pub struct ProjectNode {
659    #[prost(message, repeated, tag = "1")]
660    pub select_list: ::prost::alloc::vec::Vec<super::expr::ExprNode>,
661    /// this two field is expressing a list of usize pair, which means when project receives a
662    /// watermark with `watermark_input_cols\[i\]` column index, it should derive a new watermark
663    /// with `watermark_output_cols\[i\]`th expression
664    #[prost(uint32, repeated, tag = "2")]
665    pub watermark_input_cols: ::prost::alloc::vec::Vec<u32>,
666    #[prost(uint32, repeated, tag = "3")]
667    pub watermark_output_cols: ::prost::alloc::vec::Vec<u32>,
668    #[prost(uint32, repeated, tag = "4")]
669    pub nondecreasing_exprs: ::prost::alloc::vec::Vec<u32>,
670    /// Whether there are likely no-op updates in the output chunks, so that eliminating them with
671    /// `StreamChunk::eliminate_adjacent_noop_update` could be beneficial.
672    #[prost(bool, tag = "5")]
673    pub noop_update_hint: bool,
674}
675#[derive(prost_helpers::AnyPB)]
676#[derive(Clone, PartialEq, ::prost::Message)]
677pub struct FilterNode {
678    #[prost(message, optional, tag = "1")]
679    pub search_condition: ::core::option::Option<super::expr::ExprNode>,
680}
681#[derive(prost_helpers::AnyPB)]
682#[derive(Clone, PartialEq, ::prost::Message)]
683pub struct ChangeLogNode {
684    /// Whether or not there is an op in the final output.
685    #[prost(bool, tag = "1")]
686    pub need_op: bool,
687    #[prost(uint32, repeated, tag = "2")]
688    pub distribution_keys: ::prost::alloc::vec::Vec<u32>,
689}
690#[derive(prost_helpers::AnyPB)]
691#[derive(Clone, PartialEq, ::prost::Message)]
692pub struct CdcFilterNode {
693    #[prost(message, optional, tag = "1")]
694    pub search_condition: ::core::option::Option<super::expr::ExprNode>,
695    #[prost(uint32, tag = "2", wrapper = "crate::id::SourceId")]
696    pub upstream_source_id: crate::id::SourceId,
697}
698/// A materialized view is regarded as a table.
699/// In addition, we also specify primary key to MV for efficient point lookup during update and deletion.
700///
701/// The node will be used for both create mv and create index.
702/// - When creating mv, `pk == distribution_key == column_orders`.
703/// - When creating index, `column_orders` will contain both
704///    arrange columns and pk columns, while distribution key will be arrange columns.
705#[derive(prost_helpers::AnyPB)]
706#[derive(Clone, PartialEq, ::prost::Message)]
707pub struct MaterializeNode {
708    #[prost(uint32, tag = "1", wrapper = "crate::id::TableId")]
709    pub table_id: crate::id::TableId,
710    /// Column indexes and orders of primary key.
711    #[prost(message, repeated, tag = "2")]
712    pub column_orders: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
713    /// Primary materialized table that stores the final result data.
714    /// Purpose: This is the main table that users query against. It contains the
715    ///           complete materialized view results with all columns from the SELECT clause.
716    /// Schema: Matches the output schema of the materialized view query
717    /// PK: Determined by the stream key of the materialized view
718    /// Distribution: Hash distributed by primary key columns for parallel processing
719    #[prost(message, optional, tag = "3")]
720    pub table: ::core::option::Option<super::catalog::Table>,
721    /// Staging table for refreshable materialized views during refresh operations.
722    /// Purpose: Temporary storage for collecting new/updated data during refresh.
723    ///           This allows atomic replacement of old data with refreshed data.
724    /// Schema: Contains only the primary key columns from the main table (pk-only table)
725    ///          - All PK columns with same data types as main table
726    ///          - Same primary key definition as main table
727    /// Usage: Active only during refresh operations, empty otherwise
728    /// Lifecycle: Created -> populated during refresh -> merged with main table -> cleared
729    #[prost(message, optional, tag = "5")]
730    pub staging_table: ::core::option::Option<super::catalog::Table>,
731    /// Progress tracking table for refreshable materialized views.
732    /// Purpose: Tracks refresh operation progress per VirtualNode to enable fault-tolerant
733    ///           resumable refresh operations. Stores checkpoint information for recovery.
734    /// Schema: Simplified variable-length schema (following backfill pattern):
735    ///          - vnode (i32): VirtualNode identifier (PK)
736    ///          - current_pos...: Current processing position (variable PK fields from upstream)
737    ///          - is_completed (bool): Whether this vnode has completed processing
738    ///          - processed_rows (i64): Number of rows processed so far in this vnode
739    /// PK: vnode (allows efficient per-vnode progress lookup and updates)
740    /// Distribution: Hash distributed by vnode for parallel progress tracking
741    /// Usage: Persists across refresh operations for resumability
742    /// Note: Stage info is now tracked in MaterializeExecutor memory for simplicity
743    #[prost(message, optional, tag = "6")]
744    pub refresh_progress_table: ::core::option::Option<super::catalog::Table>,
745    /// Whether the table can clean itself by TTL watermark, i.e., is defined with `WATERMARK ... WITH TTL`.
746    #[prost(bool, tag = "7")]
747    pub cleaned_by_ttl_watermark: bool,
748}
749#[derive(prost_helpers::AnyPB)]
750#[derive(Clone, PartialEq, ::prost::Message)]
751pub struct AggCallState {
752    #[prost(oneof = "agg_call_state::Inner", tags = "1, 3")]
753    pub inner: ::core::option::Option<agg_call_state::Inner>,
754}
755/// Nested message and enum types in `AggCallState`.
756pub mod agg_call_state {
757    /// the state is stored in the intermediate state table. used for count/sum/append-only extreme.
758    #[derive(prost_helpers::AnyPB)]
759    #[derive(Clone, Copy, PartialEq, ::prost::Message)]
760    pub struct ValueState {}
761    /// use the some column of the Upstream's materialization as the AggCall's state, used for extreme/string_agg/array_agg.
762    #[derive(prost_helpers::AnyPB)]
763    #[derive(Clone, PartialEq, ::prost::Message)]
764    pub struct MaterializedInputState {
765        #[prost(message, optional, tag = "1")]
766        pub table: ::core::option::Option<super::super::catalog::Table>,
767        /// for constructing state table column mapping
768        #[prost(uint32, repeated, tag = "2")]
769        pub included_upstream_indices: ::prost::alloc::vec::Vec<u32>,
770        #[prost(uint32, repeated, tag = "3")]
771        pub table_value_indices: ::prost::alloc::vec::Vec<u32>,
772        #[prost(message, repeated, tag = "4")]
773        pub order_columns: ::prost::alloc::vec::Vec<super::super::common::ColumnOrder>,
774    }
775    #[derive(prost_helpers::AnyPB)]
776    #[derive(Clone, PartialEq, ::prost::Oneof)]
777    pub enum Inner {
778        #[prost(message, tag = "1")]
779        ValueState(ValueState),
780        #[prost(message, tag = "3")]
781        MaterializedInputState(MaterializedInputState),
782    }
783}
784#[derive(prost_helpers::AnyPB)]
785#[derive(Clone, PartialEq, ::prost::Message)]
786pub struct SimpleAggNode {
787    #[prost(message, repeated, tag = "1")]
788    pub agg_calls: ::prost::alloc::vec::Vec<super::expr::AggCall>,
789    #[prost(message, repeated, tag = "3")]
790    pub agg_call_states: ::prost::alloc::vec::Vec<AggCallState>,
791    #[prost(message, optional, tag = "4")]
792    pub intermediate_state_table: ::core::option::Option<super::catalog::Table>,
793    /// Whether to optimize for append only stream.
794    /// It is true when the input is append-only
795    #[prost(bool, tag = "5")]
796    pub is_append_only: bool,
797    #[prost(map = "uint32, message", tag = "6")]
798    pub distinct_dedup_tables: ::std::collections::HashMap<u32, super::catalog::Table>,
799    #[prost(uint32, tag = "7")]
800    pub row_count_index: u32,
801    #[prost(enumeration = "AggNodeVersion", tag = "8")]
802    pub version: i32,
803    /// Required by the downstream `RowMergeNode`,
804    /// currently only used by the `approx_percentile`'s two phase plan
805    #[prost(bool, tag = "9")]
806    pub must_output_per_barrier: bool,
807}
808#[derive(prost_helpers::AnyPB)]
809#[derive(Clone, PartialEq, ::prost::Message)]
810pub struct HashAggNode {
811    #[prost(uint32, repeated, tag = "1")]
812    pub group_key: ::prost::alloc::vec::Vec<u32>,
813    #[prost(message, repeated, tag = "2")]
814    pub agg_calls: ::prost::alloc::vec::Vec<super::expr::AggCall>,
815    #[prost(message, repeated, tag = "3")]
816    pub agg_call_states: ::prost::alloc::vec::Vec<AggCallState>,
817    #[prost(message, optional, tag = "4")]
818    pub intermediate_state_table: ::core::option::Option<super::catalog::Table>,
819    /// Whether to optimize for append only stream.
820    /// It is true when the input is append-only
821    #[prost(bool, tag = "5")]
822    pub is_append_only: bool,
823    #[prost(map = "uint32, message", tag = "6")]
824    pub distinct_dedup_tables: ::std::collections::HashMap<u32, super::catalog::Table>,
825    #[prost(uint32, tag = "7")]
826    pub row_count_index: u32,
827    #[prost(bool, tag = "8")]
828    pub emit_on_window_close: bool,
829    #[prost(enumeration = "AggNodeVersion", tag = "9")]
830    pub version: i32,
831}
832#[derive(prost_helpers::AnyPB)]
833#[derive(Clone, PartialEq, ::prost::Message)]
834pub struct TopNNode {
835    /// 0 means no limit as limit of 0 means this node should be optimized away
836    #[prost(uint64, tag = "1")]
837    pub limit: u64,
838    #[prost(uint64, tag = "2")]
839    pub offset: u64,
840    #[prost(message, optional, tag = "3")]
841    pub table: ::core::option::Option<super::catalog::Table>,
842    #[prost(message, repeated, tag = "4")]
843    pub order_by: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
844    #[prost(bool, tag = "5")]
845    pub with_ties: bool,
846}
847#[derive(prost_helpers::AnyPB)]
848#[derive(Clone, PartialEq, ::prost::Message)]
849pub struct GroupTopNNode {
850    /// 0 means no limit as limit of 0 means this node should be optimized away
851    #[prost(uint64, tag = "1")]
852    pub limit: u64,
853    #[prost(uint64, tag = "2")]
854    pub offset: u64,
855    #[prost(uint32, repeated, tag = "3")]
856    pub group_key: ::prost::alloc::vec::Vec<u32>,
857    #[prost(message, optional, tag = "4")]
858    pub table: ::core::option::Option<super::catalog::Table>,
859    #[prost(message, repeated, tag = "5")]
860    pub order_by: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
861    #[prost(bool, tag = "6")]
862    pub with_ties: bool,
863}
864#[derive(prost_helpers::AnyPB)]
865#[derive(Clone, PartialEq, ::prost::Message)]
866pub struct DeltaExpression {
867    #[prost(enumeration = "super::expr::expr_node::Type", tag = "1")]
868    pub delta_type: i32,
869    #[prost(message, optional, tag = "2")]
870    pub delta: ::core::option::Option<super::expr::ExprNode>,
871}
872/// Deprecated: Use InequalityPairV2 instead.
873#[derive(prost_helpers::AnyPB)]
874#[derive(Clone, PartialEq, ::prost::Message)]
875pub struct InequalityPair {
876    /// Input index of greater side of inequality.
877    #[prost(uint32, tag = "1")]
878    pub key_required_larger: u32,
879    /// Input index of less side of inequality.
880    #[prost(uint32, tag = "2")]
881    pub key_required_smaller: u32,
882    /// Whether this condition is used to clean state table of `HashJoinExecutor`.
883    #[prost(bool, tag = "3")]
884    pub clean_state: bool,
885    /// greater >= less + delta_expression, if `None`, it represents that greater >= less
886    #[prost(message, optional, tag = "4")]
887    pub delta_expression: ::core::option::Option<DeltaExpression>,
888}
889#[derive(prost_helpers::AnyPB)]
890#[derive(Clone, Copy, PartialEq, ::prost::Message)]
891pub struct InequalityPairV2 {
892    /// Index of the left side of the inequality (from left input).
893    #[prost(uint32, tag = "1")]
894    pub left_idx: u32,
895    /// Index of the right side of the inequality (from right input, NOT offset by left_cols_num).
896    #[prost(uint32, tag = "2")]
897    pub right_idx: u32,
898    /// Whether this condition is used to clean left state table of `HashJoinExecutor`.
899    #[prost(bool, tag = "3")]
900    pub clean_left_state: bool,
901    /// Whether this condition is used to clean right state table of `HashJoinExecutor`.
902    #[prost(bool, tag = "4")]
903    pub clean_right_state: bool,
904    /// Comparison operator: left_col `<op>` right_col (e.g., <, <=, >, >=).
905    #[prost(enumeration = "InequalityType", tag = "5")]
906    pub op: i32,
907}
908#[derive(prost_helpers::AnyPB)]
909#[derive(Clone, PartialEq, ::prost::Message)]
910pub struct HashJoinNode {
911    #[prost(enumeration = "super::plan_common::JoinType", tag = "1")]
912    pub join_type: i32,
913    #[prost(int32, repeated, tag = "2")]
914    pub left_key: ::prost::alloc::vec::Vec<i32>,
915    #[prost(int32, repeated, tag = "3")]
916    pub right_key: ::prost::alloc::vec::Vec<i32>,
917    #[prost(message, optional, tag = "4")]
918    pub condition: ::core::option::Option<super::expr::ExprNode>,
919    #[prost(message, repeated, tag = "5")]
920    pub inequality_pairs: ::prost::alloc::vec::Vec<InequalityPair>,
921    /// Used for internal table states.
922    #[prost(message, optional, tag = "6")]
923    pub left_table: ::core::option::Option<super::catalog::Table>,
924    /// Used for internal table states.
925    #[prost(message, optional, tag = "7")]
926    pub right_table: ::core::option::Option<super::catalog::Table>,
927    /// Used for internal table states.
928    #[prost(message, optional, tag = "8")]
929    pub left_degree_table: ::core::option::Option<super::catalog::Table>,
930    /// Used for internal table states.
931    #[prost(message, optional, tag = "9")]
932    pub right_degree_table: ::core::option::Option<super::catalog::Table>,
933    /// The output indices of current node
934    #[prost(uint32, repeated, tag = "10")]
935    pub output_indices: ::prost::alloc::vec::Vec<u32>,
936    /// Left deduped input pk indices. The pk of the left_table and
937    /// left_degree_table is  \[left_join_key | left_deduped_input_pk_indices\]
938    /// and is expected to be the shortest key which starts with
939    /// the join key and satisfies unique constrain.
940    #[prost(uint32, repeated, tag = "11")]
941    pub left_deduped_input_pk_indices: ::prost::alloc::vec::Vec<u32>,
942    /// Right deduped input pk indices. The pk of the right_table and
943    /// right_degree_table is  \[right_join_key | right_deduped_input_pk_indices\]
944    /// and is expected to be the shortest key which starts with
945    /// the join key and satisfies unique constrain.
946    #[prost(uint32, repeated, tag = "12")]
947    pub right_deduped_input_pk_indices: ::prost::alloc::vec::Vec<u32>,
948    #[prost(bool, repeated, tag = "13")]
949    pub null_safe: ::prost::alloc::vec::Vec<bool>,
950    /// Whether to optimize for append only stream.
951    /// It is true when the input is append-only
952    #[prost(bool, tag = "14")]
953    pub is_append_only: bool,
954    /// Which encoding will be used to encode join rows in operator cache.
955    /// Deprecated. Use the one from `StreamingDeveloperConfig` instead.
956    #[deprecated]
957    #[prost(enumeration = "JoinEncodingType", tag = "15")]
958    pub join_encoding_type: i32,
959    /// New inequality pairs with clearer semantics. Takes precedence over `inequality_pairs` if non-empty.
960    #[prost(message, repeated, tag = "16")]
961    pub inequality_pairs_v2: ::prost::alloc::vec::Vec<InequalityPairV2>,
962}
963#[derive(prost_helpers::AnyPB)]
964#[derive(Clone, PartialEq, ::prost::Message)]
965pub struct AsOfJoinNode {
966    #[prost(enumeration = "super::plan_common::AsOfJoinType", tag = "1")]
967    pub join_type: i32,
968    #[prost(int32, repeated, tag = "2")]
969    pub left_key: ::prost::alloc::vec::Vec<i32>,
970    #[prost(int32, repeated, tag = "3")]
971    pub right_key: ::prost::alloc::vec::Vec<i32>,
972    /// Used for internal table states.
973    #[prost(message, optional, tag = "4")]
974    pub left_table: ::core::option::Option<super::catalog::Table>,
975    /// Used for internal table states.
976    #[prost(message, optional, tag = "5")]
977    pub right_table: ::core::option::Option<super::catalog::Table>,
978    /// The output indices of current node
979    #[prost(uint32, repeated, tag = "6")]
980    pub output_indices: ::prost::alloc::vec::Vec<u32>,
981    /// Left deduped input pk indices. The pk of the left_table and
982    /// The pk of the left_table is  \[left_join_key | left_inequality_key | left_deduped_input_pk_indices\]
983    /// left_inequality_key is not used but for forward compatibility.
984    #[prost(uint32, repeated, tag = "7")]
985    pub left_deduped_input_pk_indices: ::prost::alloc::vec::Vec<u32>,
986    /// Right deduped input pk indices.
987    /// The pk of the right_table is  \[right_join_key | right_inequality_key | right_deduped_input_pk_indices\]
988    /// right_inequality_key is not used but for forward compatibility.
989    #[prost(uint32, repeated, tag = "8")]
990    pub right_deduped_input_pk_indices: ::prost::alloc::vec::Vec<u32>,
991    #[prost(bool, repeated, tag = "9")]
992    pub null_safe: ::prost::alloc::vec::Vec<bool>,
993    #[prost(message, optional, tag = "10")]
994    pub asof_desc: ::core::option::Option<super::plan_common::AsOfJoinDesc>,
995    /// Which encoding will be used to encode join rows in operator cache.
996    /// Deprecated. Use the one from `StreamingDeveloperConfig` instead.
997    #[deprecated]
998    #[prost(enumeration = "JoinEncodingType", tag = "11")]
999    pub join_encoding_type: i32,
1000}
1001#[derive(prost_helpers::AnyPB)]
1002#[derive(Clone, PartialEq, ::prost::Message)]
1003pub struct TemporalJoinNode {
1004    #[prost(enumeration = "super::plan_common::JoinType", tag = "1")]
1005    pub join_type: i32,
1006    #[prost(int32, repeated, tag = "2")]
1007    pub left_key: ::prost::alloc::vec::Vec<i32>,
1008    #[prost(int32, repeated, tag = "3")]
1009    pub right_key: ::prost::alloc::vec::Vec<i32>,
1010    #[prost(bool, repeated, tag = "4")]
1011    pub null_safe: ::prost::alloc::vec::Vec<bool>,
1012    #[prost(message, optional, tag = "5")]
1013    pub condition: ::core::option::Option<super::expr::ExprNode>,
1014    /// The output indices of current node
1015    #[prost(uint32, repeated, tag = "6")]
1016    pub output_indices: ::prost::alloc::vec::Vec<u32>,
1017    /// The table desc of the lookup side table.
1018    #[prost(message, optional, tag = "7")]
1019    pub table_desc: ::core::option::Option<super::plan_common::StorageTableDesc>,
1020    /// The output indices of the lookup side table
1021    #[prost(uint32, repeated, tag = "8")]
1022    pub table_output_indices: ::prost::alloc::vec::Vec<u32>,
1023    /// The state table used for non-append-only temporal join.
1024    #[prost(message, optional, tag = "9")]
1025    pub memo_table: ::core::option::Option<super::catalog::Table>,
1026    /// If it is a nested lool temporal join
1027    #[prost(bool, tag = "10")]
1028    pub is_nested_loop: bool,
1029}
1030#[derive(prost_helpers::AnyPB)]
1031#[derive(Clone, PartialEq, ::prost::Message)]
1032pub struct DynamicFilterNode {
1033    #[prost(uint32, tag = "1")]
1034    pub left_key: u32,
1035    /// Must be one of <, <=, >, >=
1036    #[prost(message, optional, tag = "2")]
1037    pub condition: ::core::option::Option<super::expr::ExprNode>,
1038    /// Left table stores all states with predicate possibly not NULL.
1039    #[prost(message, optional, tag = "3")]
1040    pub left_table: ::core::option::Option<super::catalog::Table>,
1041    /// Right table stores single value from RHS of predicate.
1042    #[prost(message, optional, tag = "4")]
1043    pub right_table: ::core::option::Option<super::catalog::Table>,
1044    /// If the right side's change always make the condition more relaxed.
1045    /// In other words, make more record in the left side satisfy the condition.
1046    /// If this is true, we need to store LHS records which do not match the condition in the internal table.
1047    /// When the condition changes, we will tell downstream to insert the LHS records which now match the condition.
1048    /// If this is false, we need to store RHS records which match the condition in the internal table.
1049    /// When the condition changes, we will tell downstream to delete the LHS records which now no longer match the condition.
1050    #[deprecated]
1051    #[prost(bool, tag = "5")]
1052    pub condition_always_relax: bool,
1053    /// Whether the dynamic filter can clean its left state table by watermark.
1054    #[prost(bool, tag = "6")]
1055    pub cleaned_by_watermark: bool,
1056}
1057/// Delta join with two indexes. This is a pseudo plan node generated on frontend. On meta
1058/// service, it will be rewritten into lookup joins.
1059#[derive(prost_helpers::AnyPB)]
1060#[derive(Clone, PartialEq, ::prost::Message)]
1061pub struct DeltaIndexJoinNode {
1062    #[prost(enumeration = "super::plan_common::JoinType", tag = "1")]
1063    pub join_type: i32,
1064    #[prost(int32, repeated, tag = "2")]
1065    pub left_key: ::prost::alloc::vec::Vec<i32>,
1066    #[prost(int32, repeated, tag = "3")]
1067    pub right_key: ::prost::alloc::vec::Vec<i32>,
1068    #[prost(message, optional, tag = "4")]
1069    pub condition: ::core::option::Option<super::expr::ExprNode>,
1070    /// Table id of the left index.
1071    #[prost(uint32, tag = "7", wrapper = "crate::id::TableId")]
1072    pub left_table_id: crate::id::TableId,
1073    /// Table id of the right index.
1074    #[prost(uint32, tag = "8", wrapper = "crate::id::TableId")]
1075    pub right_table_id: crate::id::TableId,
1076    /// Info about the left index
1077    #[prost(message, optional, tag = "9")]
1078    pub left_info: ::core::option::Option<ArrangementInfo>,
1079    /// Info about the right index
1080    #[prost(message, optional, tag = "10")]
1081    pub right_info: ::core::option::Option<ArrangementInfo>,
1082    /// the output indices of current node
1083    #[prost(uint32, repeated, tag = "11")]
1084    pub output_indices: ::prost::alloc::vec::Vec<u32>,
1085}
1086#[derive(prost_helpers::AnyPB)]
1087#[derive(Clone, PartialEq, ::prost::Message)]
1088pub struct HopWindowNode {
1089    #[prost(uint32, tag = "1")]
1090    pub time_col: u32,
1091    #[prost(message, optional, tag = "2")]
1092    pub window_slide: ::core::option::Option<super::data::Interval>,
1093    #[prost(message, optional, tag = "3")]
1094    pub window_size: ::core::option::Option<super::data::Interval>,
1095    #[prost(uint32, repeated, tag = "4")]
1096    pub output_indices: ::prost::alloc::vec::Vec<u32>,
1097    #[prost(message, repeated, tag = "5")]
1098    pub window_start_exprs: ::prost::alloc::vec::Vec<super::expr::ExprNode>,
1099    #[prost(message, repeated, tag = "6")]
1100    pub window_end_exprs: ::prost::alloc::vec::Vec<super::expr::ExprNode>,
1101}
1102#[derive(prost_helpers::AnyPB)]
1103#[derive(Clone, PartialEq, ::prost::Message)]
1104pub struct MergeNode {
1105    /// **WARNING**: Use this field with caution.
1106    ///
1107    /// `upstream_actor_id` stored in the plan node in `Fragment` meta model cannot be directly used.
1108    /// See `compose_fragment`.
1109    /// The field is deprecated because the upstream actor info is provided separately instead of
1110    /// injected here in the node.
1111    #[deprecated]
1112    #[prost(uint32, repeated, packed = "false", tag = "1")]
1113    pub upstream_actor_id: ::prost::alloc::vec::Vec<u32>,
1114    #[prost(uint32, tag = "2", wrapper = "crate::id::FragmentId")]
1115    pub upstream_fragment_id: crate::id::FragmentId,
1116    /// Type of the upstream dispatcher. If there's always one upstream according to this
1117    /// type, the compute node may use the `ReceiverExecutor` as an optimization.
1118    #[prost(enumeration = "DispatcherType", tag = "3")]
1119    pub upstream_dispatcher_type: i32,
1120    /// The schema of input columns. Already deprecated.
1121    #[deprecated]
1122    #[prost(message, repeated, tag = "4")]
1123    pub fields: ::prost::alloc::vec::Vec<super::plan_common::Field>,
1124}
1125/// passed from frontend to meta, used by fragmenter to generate `MergeNode`
1126/// and maybe `DispatcherNode` later.
1127#[derive(prost_helpers::AnyPB)]
1128#[derive(Clone, PartialEq, ::prost::Message)]
1129pub struct ExchangeNode {
1130    #[prost(message, optional, tag = "1")]
1131    pub strategy: ::core::option::Option<DispatchStrategy>,
1132}
1133/// StreamScanNode reads data from upstream table first, and then pass all events to downstream.
1134/// It always these 2 inputs in the following order:
1135/// 1. A MergeNode (as a placeholder) of upstream.
1136/// 2. A BatchPlanNode for the snapshot read.
1137#[derive(prost_helpers::AnyPB)]
1138#[derive(Clone, PartialEq, ::prost::Message)]
1139pub struct StreamScanNode {
1140    #[prost(uint32, tag = "1", wrapper = "crate::id::TableId")]
1141    pub table_id: crate::id::TableId,
1142    /// The columns from the upstream table that'll be internally required by this stream scan node.
1143    /// - For non-backfill stream scan node, it's the same as the output columns.
1144    /// - For backfill stream scan node, there're additionally primary key columns.
1145    #[prost(int32, repeated, tag = "2")]
1146    pub upstream_column_ids: ::prost::alloc::vec::Vec<i32>,
1147    /// The columns to be output by this stream scan node. The index is based on the internal required columns.
1148    /// - For non-backfill stream scan node, it's simply all the columns.
1149    /// - For backfill stream scan node, this strips the primary key columns if they're unnecessary.
1150    #[prost(uint32, repeated, tag = "3")]
1151    pub output_indices: ::prost::alloc::vec::Vec<u32>,
1152    /// Generally, the barrier needs to be rearranged during the MV creation process, so that data can
1153    /// be flushed to shared buffer periodically, instead of making the first epoch from batch query extra
1154    /// large. However, in some cases, e.g., shared state, the barrier cannot be rearranged in StreamScanNode.
1155    /// StreamScanType is used to decide which implementation for the StreamScanNode.
1156    #[prost(enumeration = "StreamScanType", tag = "4")]
1157    pub stream_scan_type: i32,
1158    /// / The state table used by Backfill operator for persisting internal state
1159    #[prost(message, optional, tag = "5")]
1160    pub state_table: ::core::option::Option<super::catalog::Table>,
1161    /// The upstream materialized view info used by backfill.
1162    /// Used iff `ChainType::Backfill`.
1163    #[prost(message, optional, tag = "7")]
1164    pub table_desc: ::core::option::Option<super::plan_common::StorageTableDesc>,
1165    /// The backfill rate limit for the stream scan node.
1166    #[prost(uint32, optional, tag = "8")]
1167    pub rate_limit: ::core::option::Option<u32>,
1168    /// Snapshot read every N barriers
1169    #[deprecated]
1170    #[prost(uint32, tag = "9")]
1171    pub snapshot_read_barrier_interval: u32,
1172    /// The state table used by ArrangementBackfill to replicate upstream mview's state table.
1173    /// Used iff `ChainType::ArrangementBackfill`.
1174    #[prost(message, optional, tag = "10")]
1175    pub arrangement_table: ::core::option::Option<super::catalog::Table>,
1176    #[prost(uint64, optional, tag = "11")]
1177    pub snapshot_backfill_epoch: ::core::option::Option<u64>,
1178}
1179/// Config options for CDC backfill
1180#[derive(prost_helpers::AnyPB)]
1181#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1182pub struct StreamCdcScanOptions {
1183    /// Whether skip the backfill and only consume from upstream.
1184    #[prost(bool, tag = "1")]
1185    pub disable_backfill: bool,
1186    #[prost(uint32, tag = "2")]
1187    pub snapshot_barrier_interval: u32,
1188    #[prost(uint32, tag = "3")]
1189    pub snapshot_batch_size: u32,
1190    #[prost(uint32, tag = "4")]
1191    pub backfill_parallelism: u32,
1192    #[prost(uint64, tag = "5")]
1193    pub backfill_num_rows_per_split: u64,
1194    #[prost(bool, tag = "6")]
1195    pub backfill_as_even_splits: bool,
1196    #[prost(uint32, tag = "7")]
1197    pub backfill_split_pk_column_index: u32,
1198}
1199#[derive(prost_helpers::AnyPB)]
1200#[derive(Clone, PartialEq, ::prost::Message)]
1201pub struct StreamCdcScanNode {
1202    #[prost(uint32, tag = "1", wrapper = "crate::id::TableId")]
1203    pub table_id: crate::id::TableId,
1204    /// The columns from the upstream table that'll be internally required by this stream scan node.
1205    /// Contains Primary Keys and Output columns.
1206    #[prost(int32, repeated, tag = "2")]
1207    pub upstream_column_ids: ::prost::alloc::vec::Vec<i32>,
1208    /// Strips the primary key columns if they're unnecessary.
1209    #[prost(uint32, repeated, tag = "3")]
1210    pub output_indices: ::prost::alloc::vec::Vec<u32>,
1211    /// The state table used by CdcBackfill operator for persisting internal state
1212    #[prost(message, optional, tag = "4")]
1213    pub state_table: ::core::option::Option<super::catalog::Table>,
1214    /// The external table that will be backfilled for CDC.
1215    #[prost(message, optional, tag = "5")]
1216    pub cdc_table_desc: ::core::option::Option<super::plan_common::ExternalTableDesc>,
1217    /// The backfill rate limit for the stream cdc scan node.
1218    #[prost(uint32, optional, tag = "6")]
1219    pub rate_limit: ::core::option::Option<u32>,
1220    /// Whether skip the backfill and only consume from upstream.
1221    /// keep it for backward compatibility, new stream plan will use `options.disable_backfill`
1222    #[prost(bool, tag = "7")]
1223    pub disable_backfill: bool,
1224    #[prost(message, optional, tag = "8")]
1225    pub options: ::core::option::Option<StreamCdcScanOptions>,
1226}
1227/// BatchPlanNode is used for mv on mv snapshot read.
1228/// BatchPlanNode is supposed to carry a batch plan that can be optimized with the streaming plan_common.
1229/// Currently, streaming to batch push down is not yet supported, BatchPlanNode is simply a table scan.
1230#[derive(prost_helpers::AnyPB)]
1231#[derive(Clone, PartialEq, ::prost::Message)]
1232pub struct BatchPlanNode {
1233    #[prost(message, optional, tag = "1")]
1234    pub table_desc: ::core::option::Option<super::plan_common::StorageTableDesc>,
1235    #[prost(int32, repeated, tag = "2")]
1236    pub column_ids: ::prost::alloc::vec::Vec<i32>,
1237}
1238#[derive(prost_helpers::AnyPB)]
1239#[derive(Clone, PartialEq, ::prost::Message)]
1240pub struct ArrangementInfo {
1241    /// Order key of the arrangement, including order by columns and pk from the materialize
1242    /// executor.
1243    #[prost(message, repeated, tag = "1")]
1244    pub arrange_key_orders: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
1245    /// Column descs of the arrangement
1246    #[prost(message, repeated, tag = "2")]
1247    pub column_descs: ::prost::alloc::vec::Vec<super::plan_common::ColumnDesc>,
1248    /// Used to build storage table by stream lookup join of delta join.
1249    #[prost(message, optional, tag = "4")]
1250    pub table_desc: ::core::option::Option<super::plan_common::StorageTableDesc>,
1251    /// Output index columns
1252    #[prost(uint32, repeated, tag = "5")]
1253    pub output_col_idx: ::prost::alloc::vec::Vec<u32>,
1254}
1255/// Special node for shared state, which will only be produced in fragmenter. ArrangeNode will
1256/// produce a special Materialize executor, which materializes data for downstream to query.
1257#[derive(prost_helpers::AnyPB)]
1258#[derive(Clone, PartialEq, ::prost::Message)]
1259pub struct ArrangeNode {
1260    /// Info about the arrangement
1261    #[prost(message, optional, tag = "1")]
1262    pub table_info: ::core::option::Option<ArrangementInfo>,
1263    /// Hash key of the materialize node, which is a subset of pk.
1264    #[prost(uint32, repeated, tag = "2")]
1265    pub distribution_key: ::prost::alloc::vec::Vec<u32>,
1266    /// Used for internal table states.
1267    #[prost(message, optional, tag = "3")]
1268    pub table: ::core::option::Option<super::catalog::Table>,
1269}
1270/// Special node for shared state. LookupNode will join an arrangement with a stream.
1271#[derive(prost_helpers::AnyPB)]
1272#[derive(Clone, PartialEq, ::prost::Message)]
1273pub struct LookupNode {
1274    /// Join key of the arrangement side
1275    #[prost(int32, repeated, tag = "1")]
1276    pub arrange_key: ::prost::alloc::vec::Vec<i32>,
1277    /// Join key of the stream side
1278    #[prost(int32, repeated, tag = "2")]
1279    pub stream_key: ::prost::alloc::vec::Vec<i32>,
1280    /// Whether to join the current epoch of arrangement
1281    #[prost(bool, tag = "3")]
1282    pub use_current_epoch: bool,
1283    /// Sometimes we need to re-order the output data to meet the requirement of schema.
1284    /// By default, lookup executor will produce `<arrangement side, stream side>`. We
1285    /// will then apply the column mapping to the combined result.
1286    #[prost(int32, repeated, tag = "4")]
1287    pub column_mapping: ::prost::alloc::vec::Vec<i32>,
1288    /// Info about the arrangement
1289    #[prost(message, optional, tag = "7")]
1290    pub arrangement_table_info: ::core::option::Option<ArrangementInfo>,
1291    #[prost(oneof = "lookup_node::ArrangementTableId", tags = "5, 6")]
1292    pub arrangement_table_id: ::core::option::Option<lookup_node::ArrangementTableId>,
1293}
1294/// Nested message and enum types in `LookupNode`.
1295pub mod lookup_node {
1296    #[derive(prost_helpers::AnyPB)]
1297    #[derive(Clone, Copy, PartialEq, ::prost::Oneof)]
1298    pub enum ArrangementTableId {
1299        /// Table Id of the arrangement (when created along with join plan)
1300        #[prost(uint32, tag = "5")]
1301        TableId(u32),
1302        /// Table Id of the arrangement (when using index)
1303        #[prost(uint32, tag = "6")]
1304        IndexId(u32),
1305    }
1306}
1307/// WatermarkFilter needs to filter the upstream data by the water mark.
1308#[derive(prost_helpers::AnyPB)]
1309#[derive(Clone, PartialEq, ::prost::Message)]
1310pub struct WatermarkFilterNode {
1311    /// The watermark descs
1312    #[prost(message, repeated, tag = "1")]
1313    pub watermark_descs: ::prost::alloc::vec::Vec<super::catalog::WatermarkDesc>,
1314    /// The tables used to persist watermarks, the key is vnode.
1315    #[prost(message, repeated, tag = "2")]
1316    pub tables: ::prost::alloc::vec::Vec<super::catalog::Table>,
1317}
1318/// Acts like a merger, but on different inputs.
1319#[derive(prost_helpers::AnyPB)]
1320#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1321pub struct UnionNode {}
1322/// Special node for shared state. Merge and align barrier from upstreams. Pipe inputs in order.
1323#[derive(prost_helpers::AnyPB)]
1324#[derive(Clone, PartialEq, ::prost::Message)]
1325pub struct LookupUnionNode {
1326    #[prost(uint32, repeated, tag = "1")]
1327    pub order: ::prost::alloc::vec::Vec<u32>,
1328}
1329#[derive(prost_helpers::AnyPB)]
1330#[derive(Clone, PartialEq, ::prost::Message)]
1331pub struct ExpandNode {
1332    #[prost(message, repeated, tag = "1")]
1333    pub column_subsets: ::prost::alloc::vec::Vec<expand_node::Subset>,
1334}
1335/// Nested message and enum types in `ExpandNode`.
1336pub mod expand_node {
1337    #[derive(prost_helpers::AnyPB)]
1338    #[derive(Clone, PartialEq, ::prost::Message)]
1339    pub struct Subset {
1340        #[prost(uint32, repeated, tag = "1")]
1341        pub column_indices: ::prost::alloc::vec::Vec<u32>,
1342    }
1343}
1344#[derive(prost_helpers::AnyPB)]
1345#[derive(Clone, PartialEq, ::prost::Message)]
1346pub struct ProjectSetNode {
1347    #[prost(message, repeated, tag = "1")]
1348    pub select_list: ::prost::alloc::vec::Vec<super::expr::ProjectSetSelectItem>,
1349    /// this two field is expressing a list of usize pair, which means when project receives a
1350    /// watermark with `watermark_input_cols\[i\]` column index, it should derive a new watermark
1351    /// with `watermark_output_cols\[i\]`th expression
1352    #[prost(uint32, repeated, tag = "2")]
1353    pub watermark_input_cols: ::prost::alloc::vec::Vec<u32>,
1354    #[prost(uint32, repeated, tag = "3")]
1355    pub watermark_expr_indices: ::prost::alloc::vec::Vec<u32>,
1356    #[prost(uint32, repeated, tag = "4")]
1357    pub nondecreasing_exprs: ::prost::alloc::vec::Vec<u32>,
1358}
1359/// Sorts inputs and outputs ordered data based on watermark.
1360#[derive(prost_helpers::AnyPB)]
1361#[derive(Clone, PartialEq, ::prost::Message)]
1362pub struct SortNode {
1363    /// Persists data above watermark.
1364    #[prost(message, optional, tag = "1")]
1365    pub state_table: ::core::option::Option<super::catalog::Table>,
1366    /// Column index of watermark to perform sorting.
1367    #[prost(uint32, tag = "2")]
1368    pub sort_column_index: u32,
1369}
1370/// Merges two streams from streaming and batch for data manipulation.
1371#[derive(prost_helpers::AnyPB)]
1372#[derive(Clone, PartialEq, ::prost::Message)]
1373pub struct DmlNode {
1374    /// Id of the table on which DML performs.
1375    #[prost(uint32, tag = "1", wrapper = "crate::id::TableId")]
1376    pub table_id: crate::id::TableId,
1377    /// Version of the table.
1378    #[prost(uint64, tag = "3")]
1379    pub table_version_id: u64,
1380    /// Column descriptions of the table.
1381    #[prost(message, repeated, tag = "2")]
1382    pub column_descs: ::prost::alloc::vec::Vec<super::plan_common::ColumnDesc>,
1383    #[prost(uint32, optional, tag = "4")]
1384    pub rate_limit: ::core::option::Option<u32>,
1385}
1386#[derive(prost_helpers::AnyPB)]
1387#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1388pub struct RowIdGenNode {
1389    #[prost(uint64, tag = "1")]
1390    pub row_id_index: u64,
1391}
1392#[derive(prost_helpers::AnyPB)]
1393#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1394pub struct NowModeUpdateCurrent {}
1395#[derive(prost_helpers::AnyPB)]
1396#[derive(Clone, PartialEq, ::prost::Message)]
1397pub struct NowModeGenerateSeries {
1398    #[prost(message, optional, tag = "1")]
1399    pub start_timestamp: ::core::option::Option<super::data::Datum>,
1400    #[prost(message, optional, tag = "2")]
1401    pub interval: ::core::option::Option<super::data::Datum>,
1402}
1403#[derive(prost_helpers::AnyPB)]
1404#[derive(Clone, PartialEq, ::prost::Message)]
1405pub struct NowNode {
1406    /// Persists emitted 'now'.
1407    #[prost(message, optional, tag = "1")]
1408    pub state_table: ::core::option::Option<super::catalog::Table>,
1409    #[prost(oneof = "now_node::Mode", tags = "101, 102")]
1410    pub mode: ::core::option::Option<now_node::Mode>,
1411}
1412/// Nested message and enum types in `NowNode`.
1413pub mod now_node {
1414    #[derive(prost_helpers::AnyPB)]
1415    #[derive(Clone, PartialEq, ::prost::Oneof)]
1416    pub enum Mode {
1417        #[prost(message, tag = "101")]
1418        UpdateCurrent(super::NowModeUpdateCurrent),
1419        #[prost(message, tag = "102")]
1420        GenerateSeries(super::NowModeGenerateSeries),
1421    }
1422}
1423#[derive(prost_helpers::AnyPB)]
1424#[derive(Clone, PartialEq, ::prost::Message)]
1425pub struct ValuesNode {
1426    #[prost(message, repeated, tag = "1")]
1427    pub tuples: ::prost::alloc::vec::Vec<values_node::ExprTuple>,
1428    #[prost(message, repeated, tag = "2")]
1429    pub fields: ::prost::alloc::vec::Vec<super::plan_common::Field>,
1430}
1431/// Nested message and enum types in `ValuesNode`.
1432pub mod values_node {
1433    #[derive(prost_helpers::AnyPB)]
1434    #[derive(Clone, PartialEq, ::prost::Message)]
1435    pub struct ExprTuple {
1436        #[prost(message, repeated, tag = "1")]
1437        pub cells: ::prost::alloc::vec::Vec<super::super::expr::ExprNode>,
1438    }
1439}
1440#[derive(prost_helpers::AnyPB)]
1441#[derive(Clone, PartialEq, ::prost::Message)]
1442pub struct DedupNode {
1443    #[prost(message, optional, tag = "1")]
1444    pub state_table: ::core::option::Option<super::catalog::Table>,
1445    #[prost(uint32, repeated, tag = "2")]
1446    pub dedup_column_indices: ::prost::alloc::vec::Vec<u32>,
1447}
1448#[derive(prost_helpers::AnyPB)]
1449#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1450pub struct NoOpNode {}
1451#[derive(prost_helpers::AnyPB)]
1452#[derive(Clone, PartialEq, ::prost::Message)]
1453pub struct EowcOverWindowNode {
1454    #[prost(message, repeated, tag = "1")]
1455    pub calls: ::prost::alloc::vec::Vec<super::expr::WindowFunction>,
1456    #[prost(uint32, repeated, tag = "2")]
1457    pub partition_by: ::prost::alloc::vec::Vec<u32>,
1458    /// use `repeated` in case of future extension, now only one column is allowed
1459    #[prost(message, repeated, tag = "3")]
1460    pub order_by: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
1461    #[prost(message, optional, tag = "4")]
1462    pub state_table: ::core::option::Option<super::catalog::Table>,
1463}
1464#[derive(prost_helpers::AnyPB)]
1465#[derive(Clone, PartialEq, ::prost::Message)]
1466pub struct OverWindowNode {
1467    #[prost(message, repeated, tag = "1")]
1468    pub calls: ::prost::alloc::vec::Vec<super::expr::WindowFunction>,
1469    #[prost(uint32, repeated, tag = "2")]
1470    pub partition_by: ::prost::alloc::vec::Vec<u32>,
1471    #[prost(message, repeated, tag = "3")]
1472    pub order_by: ::prost::alloc::vec::Vec<super::common::ColumnOrder>,
1473    #[prost(message, optional, tag = "4")]
1474    pub state_table: ::core::option::Option<super::catalog::Table>,
1475    /// Deprecated. Use the one from `StreamingDeveloperConfig` instead.
1476    #[deprecated]
1477    #[prost(enumeration = "OverWindowCachePolicy", tag = "5")]
1478    pub cache_policy: i32,
1479}
1480#[derive(prost_helpers::AnyPB)]
1481#[derive(Clone, Copy, PartialEq, ::prost::Message)]
1482pub struct LocalApproxPercentileNode {
1483    #[prost(double, tag = "1")]
1484    pub base: f64,
1485    #[prost(uint32, tag = "2")]
1486    pub percentile_index: u32,
1487}
1488#[derive(prost_helpers::AnyPB)]
1489#[derive(Clone, PartialEq, ::prost::Message)]
1490pub struct GlobalApproxPercentileNode {
1491    #[prost(double, tag = "1")]
1492    pub base: f64,
1493    #[prost(double, tag = "2")]
1494    pub quantile: f64,
1495    #[prost(message, optional, tag = "3")]
1496    pub bucket_state_table: ::core::option::Option<super::catalog::Table>,
1497    #[prost(message, optional, tag = "4")]
1498    pub count_state_table: ::core::option::Option<super::catalog::Table>,
1499}
1500#[derive(prost_helpers::AnyPB)]
1501#[derive(Clone, PartialEq, ::prost::Message)]
1502pub struct RowMergeNode {
1503    #[prost(message, optional, tag = "1")]
1504    pub lhs_mapping: ::core::option::Option<super::catalog::ColIndexMapping>,
1505    #[prost(message, optional, tag = "2")]
1506    pub rhs_mapping: ::core::option::Option<super::catalog::ColIndexMapping>,
1507}
1508#[derive(prost_helpers::AnyPB)]
1509#[derive(Clone, PartialEq, ::prost::Message)]
1510pub struct SyncLogStoreNode {
1511    #[prost(message, optional, tag = "1")]
1512    pub log_store_table: ::core::option::Option<super::catalog::Table>,
1513    /// Deprecated. Use the one from `StreamingDeveloperConfig` instead.
1514    #[deprecated]
1515    #[prost(uint32, optional, tag = "2")]
1516    pub pause_duration_ms: ::core::option::Option<u32>,
1517    /// Deprecated. Use the one from `StreamingDeveloperConfig` instead.
1518    #[deprecated]
1519    #[prost(uint32, optional, tag = "3")]
1520    pub buffer_size: ::core::option::Option<u32>,
1521    #[prost(bool, tag = "4")]
1522    pub aligned: bool,
1523}
1524#[derive(prost_helpers::AnyPB)]
1525#[derive(Clone, PartialEq, ::prost::Message)]
1526pub struct MaterializedExprsNode {
1527    #[prost(message, repeated, tag = "1")]
1528    pub exprs: ::prost::alloc::vec::Vec<super::expr::ExprNode>,
1529    #[prost(message, optional, tag = "2")]
1530    pub state_table: ::core::option::Option<super::catalog::Table>,
1531    #[prost(uint32, optional, tag = "3")]
1532    pub state_clean_col_idx: ::core::option::Option<u32>,
1533}
1534#[derive(prost_helpers::AnyPB)]
1535#[derive(Clone, PartialEq, ::prost::Message)]
1536pub struct VectorIndexWriteNode {
1537    #[prost(message, optional, tag = "1")]
1538    pub table: ::core::option::Option<super::catalog::Table>,
1539}
1540#[derive(prost_helpers::AnyPB)]
1541#[derive(Clone, PartialEq, ::prost::Message)]
1542pub struct VectorIndexLookupJoinNode {
1543    #[prost(message, optional, tag = "1")]
1544    pub reader_desc: ::core::option::Option<super::plan_common::VectorIndexReaderDesc>,
1545    #[prost(uint32, tag = "2")]
1546    pub vector_column_idx: u32,
1547}
1548#[derive(prost_helpers::AnyPB)]
1549#[derive(Clone, PartialEq, ::prost::Message)]
1550pub struct UpstreamSinkUnionNode {
1551    /// It is always empty in the persisted metadata, and get filled before we spawn the actors.
1552    /// The actual upstream info may be added and removed dynamically at runtime.
1553    #[prost(message, repeated, tag = "1")]
1554    pub init_upstreams: ::prost::alloc::vec::Vec<UpstreamSinkInfo>,
1555}
1556#[derive(prost_helpers::AnyPB)]
1557#[derive(Clone, PartialEq, ::prost::Message)]
1558pub struct LocalityProviderNode {
1559    /// Column indices that define locality
1560    #[prost(uint32, repeated, tag = "1")]
1561    pub locality_columns: ::prost::alloc::vec::Vec<u32>,
1562    /// State table for buffering input data
1563    #[prost(message, optional, tag = "2")]
1564    pub state_table: ::core::option::Option<super::catalog::Table>,
1565    /// Progress table for tracking backfill progress
1566    #[prost(message, optional, tag = "3")]
1567    pub progress_table: ::core::option::Option<super::catalog::Table>,
1568}
1569#[derive(prost_helpers::AnyPB)]
1570#[derive(Clone, PartialEq, ::prost::Message)]
1571pub struct EowcGapFillNode {
1572    #[prost(uint32, tag = "1")]
1573    pub time_column_index: u32,
1574    #[prost(message, optional, tag = "2")]
1575    pub interval: ::core::option::Option<super::expr::ExprNode>,
1576    #[prost(uint32, repeated, tag = "3")]
1577    pub fill_columns: ::prost::alloc::vec::Vec<u32>,
1578    #[prost(string, repeated, tag = "4")]
1579    pub fill_strategies: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1580    #[prost(message, optional, tag = "5")]
1581    pub buffer_table: ::core::option::Option<super::catalog::Table>,
1582    #[prost(message, optional, tag = "6")]
1583    pub prev_row_table: ::core::option::Option<super::catalog::Table>,
1584}
1585#[derive(prost_helpers::AnyPB)]
1586#[derive(Clone, PartialEq, ::prost::Message)]
1587pub struct GapFillNode {
1588    #[prost(uint32, tag = "1")]
1589    pub time_column_index: u32,
1590    #[prost(message, optional, tag = "2")]
1591    pub interval: ::core::option::Option<super::expr::ExprNode>,
1592    #[prost(uint32, repeated, tag = "3")]
1593    pub fill_columns: ::prost::alloc::vec::Vec<u32>,
1594    #[prost(string, repeated, tag = "4")]
1595    pub fill_strategies: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
1596    #[prost(message, optional, tag = "5")]
1597    pub state_table: ::core::option::Option<super::catalog::Table>,
1598}
1599#[derive(prost_helpers::AnyPB)]
1600#[derive(Clone, PartialEq, ::prost::Message)]
1601pub struct StreamNode {
1602    /// The id for the operator. This is local per mview.
1603    /// TODO: should better be a uint32.
1604    #[prost(uint64, tag = "1", wrapper = "crate::id::StreamNodeLocalOperatorId")]
1605    pub operator_id: crate::id::StreamNodeLocalOperatorId,
1606    /// Child node in plan aka. upstream nodes in the streaming DAG
1607    #[prost(message, repeated, tag = "3")]
1608    pub input: ::prost::alloc::vec::Vec<StreamNode>,
1609    #[prost(uint32, repeated, tag = "2")]
1610    pub stream_key: ::prost::alloc::vec::Vec<u32>,
1611    #[prost(enumeration = "stream_node::StreamKind", tag = "24")]
1612    pub stream_kind: i32,
1613    #[prost(string, tag = "18")]
1614    pub identity: ::prost::alloc::string::String,
1615    /// The schema of the plan node
1616    #[prost(message, repeated, tag = "19")]
1617    pub fields: ::prost::alloc::vec::Vec<super::plan_common::Field>,
1618    #[prost(
1619        oneof = "stream_node::NodeBody",
1620        tags = "100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155"
1621    )]
1622    pub node_body: ::core::option::Option<stream_node::NodeBody>,
1623}
1624/// Nested message and enum types in `StreamNode`.
1625pub mod stream_node {
1626    /// This field used to be a `bool append_only`.
1627    /// Enum variants are ordered for backwards compatibility.
1628    #[derive(prost_helpers::AnyPB)]
1629    #[derive(
1630        Clone,
1631        Copy,
1632        Debug,
1633        PartialEq,
1634        Eq,
1635        Hash,
1636        PartialOrd,
1637        Ord,
1638        ::prost::Enumeration
1639    )]
1640    #[repr(i32)]
1641    pub enum StreamKind {
1642        /// buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX
1643        Retract = 0,
1644        AppendOnly = 1,
1645        Upsert = 2,
1646    }
1647    impl StreamKind {
1648        /// String value of the enum field names used in the ProtoBuf definition.
1649        ///
1650        /// The values are not transformed in any way and thus are considered stable
1651        /// (if the ProtoBuf definition does not change) and safe for programmatic use.
1652        pub fn as_str_name(&self) -> &'static str {
1653            match self {
1654                Self::Retract => "STREAM_KIND_RETRACT",
1655                Self::AppendOnly => "STREAM_KIND_APPEND_ONLY",
1656                Self::Upsert => "STREAM_KIND_UPSERT",
1657            }
1658        }
1659        /// Creates an enum from field names used in the ProtoBuf definition.
1660        pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
1661            match value {
1662                "STREAM_KIND_RETRACT" => Some(Self::Retract),
1663                "STREAM_KIND_APPEND_ONLY" => Some(Self::AppendOnly),
1664                "STREAM_KIND_UPSERT" => Some(Self::Upsert),
1665                _ => None,
1666            }
1667        }
1668    }
1669    #[derive(prost_helpers::AnyPB)]
1670    #[derive(::enum_as_inner::EnumAsInner, ::strum::Display, ::strum::EnumDiscriminants)]
1671    #[strum_discriminants(derive(::strum::Display, Hash))]
1672    #[derive(Clone, PartialEq, ::prost::Oneof)]
1673    pub enum NodeBody {
1674        #[prost(message, tag = "100")]
1675        Source(::prost::alloc::boxed::Box<super::SourceNode>),
1676        #[prost(message, tag = "101")]
1677        Project(::prost::alloc::boxed::Box<super::ProjectNode>),
1678        #[prost(message, tag = "102")]
1679        Filter(::prost::alloc::boxed::Box<super::FilterNode>),
1680        #[prost(message, tag = "103")]
1681        Materialize(::prost::alloc::boxed::Box<super::MaterializeNode>),
1682        #[prost(message, tag = "104")]
1683        StatelessSimpleAgg(::prost::alloc::boxed::Box<super::SimpleAggNode>),
1684        #[prost(message, tag = "105")]
1685        SimpleAgg(::prost::alloc::boxed::Box<super::SimpleAggNode>),
1686        #[prost(message, tag = "106")]
1687        HashAgg(::prost::alloc::boxed::Box<super::HashAggNode>),
1688        #[prost(message, tag = "107")]
1689        AppendOnlyTopN(::prost::alloc::boxed::Box<super::TopNNode>),
1690        #[prost(message, tag = "108")]
1691        HashJoin(::prost::alloc::boxed::Box<super::HashJoinNode>),
1692        #[prost(message, tag = "109")]
1693        TopN(::prost::alloc::boxed::Box<super::TopNNode>),
1694        #[prost(message, tag = "110")]
1695        HopWindow(::prost::alloc::boxed::Box<super::HopWindowNode>),
1696        #[prost(message, tag = "111")]
1697        Merge(::prost::alloc::boxed::Box<super::MergeNode>),
1698        #[prost(message, tag = "112")]
1699        Exchange(::prost::alloc::boxed::Box<super::ExchangeNode>),
1700        #[prost(message, tag = "113")]
1701        StreamScan(::prost::alloc::boxed::Box<super::StreamScanNode>),
1702        #[prost(message, tag = "114")]
1703        BatchPlan(::prost::alloc::boxed::Box<super::BatchPlanNode>),
1704        #[prost(message, tag = "115")]
1705        Lookup(::prost::alloc::boxed::Box<super::LookupNode>),
1706        #[prost(message, tag = "116")]
1707        Arrange(::prost::alloc::boxed::Box<super::ArrangeNode>),
1708        #[prost(message, tag = "117")]
1709        LookupUnion(::prost::alloc::boxed::Box<super::LookupUnionNode>),
1710        #[prost(message, tag = "118")]
1711        Union(super::UnionNode),
1712        #[prost(message, tag = "119")]
1713        DeltaIndexJoin(::prost::alloc::boxed::Box<super::DeltaIndexJoinNode>),
1714        #[prost(message, tag = "120")]
1715        Sink(::prost::alloc::boxed::Box<super::SinkNode>),
1716        #[prost(message, tag = "121")]
1717        Expand(::prost::alloc::boxed::Box<super::ExpandNode>),
1718        #[prost(message, tag = "122")]
1719        DynamicFilter(::prost::alloc::boxed::Box<super::DynamicFilterNode>),
1720        #[prost(message, tag = "123")]
1721        ProjectSet(::prost::alloc::boxed::Box<super::ProjectSetNode>),
1722        #[prost(message, tag = "124")]
1723        GroupTopN(::prost::alloc::boxed::Box<super::GroupTopNNode>),
1724        #[prost(message, tag = "125")]
1725        Sort(::prost::alloc::boxed::Box<super::SortNode>),
1726        #[prost(message, tag = "126")]
1727        WatermarkFilter(::prost::alloc::boxed::Box<super::WatermarkFilterNode>),
1728        #[prost(message, tag = "127")]
1729        Dml(::prost::alloc::boxed::Box<super::DmlNode>),
1730        #[prost(message, tag = "128")]
1731        RowIdGen(::prost::alloc::boxed::Box<super::RowIdGenNode>),
1732        #[prost(message, tag = "129")]
1733        Now(::prost::alloc::boxed::Box<super::NowNode>),
1734        #[prost(message, tag = "130")]
1735        AppendOnlyGroupTopN(::prost::alloc::boxed::Box<super::GroupTopNNode>),
1736        #[prost(message, tag = "131")]
1737        TemporalJoin(::prost::alloc::boxed::Box<super::TemporalJoinNode>),
1738        #[prost(message, tag = "132")]
1739        BarrierRecv(::prost::alloc::boxed::Box<super::BarrierRecvNode>),
1740        #[prost(message, tag = "133")]
1741        Values(::prost::alloc::boxed::Box<super::ValuesNode>),
1742        #[prost(message, tag = "134")]
1743        AppendOnlyDedup(::prost::alloc::boxed::Box<super::DedupNode>),
1744        #[prost(message, tag = "135")]
1745        NoOp(super::NoOpNode),
1746        #[prost(message, tag = "136")]
1747        EowcOverWindow(::prost::alloc::boxed::Box<super::EowcOverWindowNode>),
1748        #[prost(message, tag = "137")]
1749        OverWindow(::prost::alloc::boxed::Box<super::OverWindowNode>),
1750        #[prost(message, tag = "138")]
1751        StreamFsFetch(::prost::alloc::boxed::Box<super::StreamFsFetchNode>),
1752        #[prost(message, tag = "139")]
1753        StreamCdcScan(::prost::alloc::boxed::Box<super::StreamCdcScanNode>),
1754        #[prost(message, tag = "140")]
1755        CdcFilter(::prost::alloc::boxed::Box<super::CdcFilterNode>),
1756        #[prost(message, tag = "142")]
1757        SourceBackfill(::prost::alloc::boxed::Box<super::SourceBackfillNode>),
1758        #[prost(message, tag = "143")]
1759        Changelog(::prost::alloc::boxed::Box<super::ChangeLogNode>),
1760        #[prost(message, tag = "144")]
1761        LocalApproxPercentile(
1762            ::prost::alloc::boxed::Box<super::LocalApproxPercentileNode>,
1763        ),
1764        #[prost(message, tag = "145")]
1765        GlobalApproxPercentile(
1766            ::prost::alloc::boxed::Box<super::GlobalApproxPercentileNode>,
1767        ),
1768        #[prost(message, tag = "146")]
1769        RowMerge(::prost::alloc::boxed::Box<super::RowMergeNode>),
1770        #[prost(message, tag = "147")]
1771        AsOfJoin(::prost::alloc::boxed::Box<super::AsOfJoinNode>),
1772        #[prost(message, tag = "148")]
1773        SyncLogStore(::prost::alloc::boxed::Box<super::SyncLogStoreNode>),
1774        #[prost(message, tag = "149")]
1775        MaterializedExprs(::prost::alloc::boxed::Box<super::MaterializedExprsNode>),
1776        #[prost(message, tag = "150")]
1777        VectorIndexWrite(::prost::alloc::boxed::Box<super::VectorIndexWriteNode>),
1778        #[prost(message, tag = "151")]
1779        UpstreamSinkUnion(::prost::alloc::boxed::Box<super::UpstreamSinkUnionNode>),
1780        #[prost(message, tag = "152")]
1781        LocalityProvider(::prost::alloc::boxed::Box<super::LocalityProviderNode>),
1782        #[prost(message, tag = "153")]
1783        EowcGapFill(::prost::alloc::boxed::Box<super::EowcGapFillNode>),
1784        #[prost(message, tag = "154")]
1785        GapFill(::prost::alloc::boxed::Box<super::GapFillNode>),
1786        #[prost(message, tag = "155")]
1787        VectorIndexLookupJoin(
1788            ::prost::alloc::boxed::Box<super::VectorIndexLookupJoinNode>,
1789        ),
1790    }
1791}
1792/// The method to map the upstream columns in the dispatcher before dispatching.
1793///
1794/// - For intra-job exchange, typically the upstream and downstream columns are the same. `indices`
1795///    will be `0..len` and `types` will be empty.
1796///
1797/// - For inter-job exchange,
1798///    * if the downstream only requires a subset of the upstream columns, `indices` will be the
1799///      indices of the required columns in the upstream columns.
1800///    * if some columns are added to the upstream, `indices` will help to maintain the same schema
1801///      from the view of the downstream.
1802///    * if some columns are altered to different (composite) types, `types` will be used to convert
1803///      the upstream columns to the downstream columns to maintain the same schema.
1804#[derive(prost_helpers::AnyPB)]
1805#[derive(Clone, PartialEq, ::prost::Message)]
1806pub struct DispatchOutputMapping {
1807    /// Indices of the columns to output.
1808    #[prost(uint32, repeated, tag = "1")]
1809    pub indices: ::prost::alloc::vec::Vec<u32>,
1810    /// Besides the indices, we may also need to convert the types of some columns.
1811    /// - If no type conversion is needed, this field will be empty.
1812    /// - If type conversion is needed, this will have the same length as `indices`. Only columns with
1813    ///    type conversion will have `upstream` and `downstream` field set.
1814    #[prost(message, repeated, tag = "2")]
1815    pub types: ::prost::alloc::vec::Vec<dispatch_output_mapping::TypePair>,
1816}
1817/// Nested message and enum types in `DispatchOutputMapping`.
1818pub mod dispatch_output_mapping {
1819    #[derive(prost_helpers::AnyPB)]
1820    #[derive(Clone, PartialEq, ::prost::Message)]
1821    pub struct TypePair {
1822        #[prost(message, optional, tag = "1")]
1823        pub upstream: ::core::option::Option<super::super::data::DataType>,
1824        #[prost(message, optional, tag = "2")]
1825        pub downstream: ::core::option::Option<super::super::data::DataType>,
1826    }
1827}
1828/// The property of an edge in the fragment graph.
1829/// This is essientially a "logical" version of `Dispatcher`. See the doc of `Dispatcher` for more details.
1830#[derive(prost_helpers::AnyPB)]
1831#[derive(Clone, PartialEq, ::prost::Message)]
1832pub struct DispatchStrategy {
1833    #[prost(enumeration = "DispatcherType", tag = "1")]
1834    pub r#type: i32,
1835    #[prost(uint32, repeated, tag = "2")]
1836    pub dist_key_indices: ::prost::alloc::vec::Vec<u32>,
1837    #[prost(message, optional, tag = "3")]
1838    pub output_mapping: ::core::option::Option<DispatchOutputMapping>,
1839}
1840/// A dispatcher redistribute messages.
1841/// We encode both the type and other usage information in the proto.
1842#[derive(prost_helpers::AnyPB)]
1843#[derive(Clone, PartialEq, ::prost::Message)]
1844pub struct Dispatcher {
1845    #[prost(enumeration = "DispatcherType", tag = "1")]
1846    pub r#type: i32,
1847    /// Indices of the columns to be used for hashing.
1848    /// For dispatcher types other than HASH, this is ignored.
1849    #[prost(uint32, repeated, tag = "2")]
1850    pub dist_key_indices: ::prost::alloc::vec::Vec<u32>,
1851    /// The method to map the upstream columns in the dispatcher before dispatching.
1852    #[prost(message, optional, tag = "6")]
1853    pub output_mapping: ::core::option::Option<DispatchOutputMapping>,
1854    /// The hash mapping for consistent hash.
1855    /// For dispatcher types other than HASH, this is ignored.
1856    #[prost(message, optional, tag = "3")]
1857    pub hash_mapping: ::core::option::Option<ActorMapping>,
1858    /// Dispatcher can be uniquely identified by a combination of actor id and dispatcher id.
1859    /// This is exactly the same as its downstream fragment id.
1860    #[prost(uint32, tag = "4", wrapper = "crate::id::FragmentId")]
1861    pub dispatcher_id: crate::id::FragmentId,
1862    /// Number of downstreams decides how many endpoints a dispatcher should dispatch.
1863    #[prost(uint32, repeated, tag = "5", wrapper = "crate::id::ActorId")]
1864    pub downstream_actor_id: ::prost::alloc::vec::Vec<crate::id::ActorId>,
1865}
1866/// A StreamActor is a running fragment of the overall stream graph,
1867#[derive(prost_helpers::AnyPB)]
1868#[derive(Clone, PartialEq, ::prost::Message)]
1869pub struct StreamActor {
1870    #[prost(uint32, tag = "1", wrapper = "crate::id::ActorId")]
1871    pub actor_id: crate::id::ActorId,
1872    #[prost(uint32, tag = "2", wrapper = "crate::id::FragmentId")]
1873    pub fragment_id: crate::id::FragmentId,
1874    #[prost(message, repeated, tag = "4")]
1875    pub dispatcher: ::prost::alloc::vec::Vec<Dispatcher>,
1876    /// Vnodes that the executors in this actor own.
1877    /// If the fragment is a singleton, this field will not be set and leave a `None`.
1878    #[prost(message, optional, tag = "8")]
1879    pub vnode_bitmap: ::core::option::Option<super::common::Buffer>,
1880    /// The SQL definition of this materialized view. Used for debugging only.
1881    #[prost(string, tag = "9")]
1882    pub mview_definition: ::prost::alloc::string::String,
1883    /// Provide the necessary context, e.g. session info like time zone, for the actor.
1884    #[prost(message, optional, tag = "10")]
1885    pub expr_context: ::core::option::Option<super::plan_common::ExprContext>,
1886    /// The config override for this actor.
1887    #[prost(string, tag = "11")]
1888    pub config_override: ::prost::alloc::string::String,
1889}
1890/// The streaming context associated with a stream plan
1891#[derive(prost_helpers::AnyPB)]
1892#[derive(Clone, PartialEq, ::prost::Message)]
1893pub struct StreamContext {
1894    /// The timezone associated with the streaming plan. Only applies to MV for now.
1895    #[prost(string, tag = "1")]
1896    pub timezone: ::prost::alloc::string::String,
1897    /// The partial config of this job to override the global config.
1898    #[prost(string, tag = "2")]
1899    pub config_override: ::prost::alloc::string::String,
1900}
1901#[derive(prost_helpers::AnyPB)]
1902#[derive(Clone, PartialEq, ::prost::Message)]
1903pub struct BackfillOrder {
1904    #[prost(map = "uint32, message", tag = "1")]
1905    pub order: ::std::collections::HashMap<u32, super::common::Uint32Vector>,
1906}
1907/// Representation of a graph of stream fragments.
1908/// Generated by the fragmenter in the frontend, only used in DDL requests and never persisted.
1909///
1910/// For the persisted form, see `TableFragments`.
1911#[derive(prost_helpers::AnyPB)]
1912#[derive(Clone, PartialEq, ::prost::Message)]
1913pub struct StreamFragmentGraph {
1914    /// all the fragments in the graph.
1915    #[prost(map = "uint32, message", tag = "1", wrapper = "crate::id::FragmentId")]
1916    pub fragments: ::std::collections::HashMap<
1917        crate::id::FragmentId,
1918        stream_fragment_graph::StreamFragment,
1919    >,
1920    /// edges between fragments.
1921    #[prost(message, repeated, tag = "2")]
1922    pub edges: ::prost::alloc::vec::Vec<stream_fragment_graph::StreamFragmentEdge>,
1923    #[prost(uint32, repeated, tag = "3", wrapper = "crate::id::TableId")]
1924    pub dependent_table_ids: ::prost::alloc::vec::Vec<crate::id::TableId>,
1925    #[prost(uint32, tag = "4")]
1926    pub table_ids_cnt: u32,
1927    #[prost(message, optional, tag = "5")]
1928    pub ctx: ::core::option::Option<StreamContext>,
1929    /// If none, default parallelism will be applied.
1930    #[prost(message, optional, tag = "6")]
1931    pub parallelism: ::core::option::Option<stream_fragment_graph::Parallelism>,
1932    /// Parallelism to use during backfill. Falls back to `parallelism` if unset.
1933    #[prost(message, optional, tag = "9")]
1934    pub backfill_parallelism: ::core::option::Option<stream_fragment_graph::Parallelism>,
1935    /// Specified max parallelism, i.e., expected vnode count for the graph.
1936    ///
1937    /// The scheduler on the meta service will use this as a hint to decide the vnode count
1938    /// for each fragment.
1939    ///
1940    /// Note that the actual vnode count may be different from this value.
1941    /// For example, a no-shuffle exchange between current fragment graph and an existing
1942    /// upstream fragment graph requires two fragments to be in the same distribution,
1943    /// thus the same vnode count.
1944    #[prost(uint32, tag = "7")]
1945    pub max_parallelism: u32,
1946    /// The backfill order strategy for the fragments.
1947    #[prost(message, optional, tag = "8")]
1948    pub backfill_order: ::core::option::Option<BackfillOrder>,
1949}
1950/// Nested message and enum types in `StreamFragmentGraph`.
1951pub mod stream_fragment_graph {
1952    #[derive(prost_helpers::AnyPB)]
1953    #[derive(Clone, PartialEq, ::prost::Message)]
1954    pub struct StreamFragment {
1955        /// 0-based on frontend, and will be rewritten to global id on meta.
1956        #[prost(uint32, tag = "1", wrapper = "crate::id::FragmentId")]
1957        pub fragment_id: crate::id::FragmentId,
1958        /// root stream node in this fragment.
1959        #[prost(message, optional, tag = "2")]
1960        pub node: ::core::option::Option<super::StreamNode>,
1961        /// Bitwise-OR of `FragmentTypeFlag`s
1962        #[prost(uint32, tag = "3")]
1963        pub fragment_type_mask: u32,
1964        /// Mark whether this fragment requires exactly one actor.
1965        /// Note: if this is `false`, the fragment may still be a singleton according to the scheduler.
1966        /// One should check `meta.Fragment.distribution_type` for the final result.
1967        #[prost(bool, tag = "4")]
1968        pub requires_singleton: bool,
1969    }
1970    #[derive(prost_helpers::AnyPB)]
1971    #[derive(Clone, PartialEq, ::prost::Message)]
1972    pub struct StreamFragmentEdge {
1973        /// Dispatch strategy for the fragment.
1974        #[prost(message, optional, tag = "1")]
1975        pub dispatch_strategy: ::core::option::Option<super::DispatchStrategy>,
1976        /// A unique identifier of this edge. Generally it should be exchange node's operator id. When
1977        /// rewriting fragments into delta joins or when inserting 1-to-1 exchange, there will be
1978        /// virtual links generated.
1979        #[prost(uint64, tag = "3")]
1980        pub link_id: u64,
1981        #[prost(uint32, tag = "4", wrapper = "crate::id::FragmentId")]
1982        pub upstream_id: crate::id::FragmentId,
1983        #[prost(uint32, tag = "5", wrapper = "crate::id::FragmentId")]
1984        pub downstream_id: crate::id::FragmentId,
1985    }
1986    #[derive(prost_helpers::AnyPB)]
1987    #[derive(Clone, Copy, PartialEq, ::prost::Message)]
1988    pub struct Parallelism {
1989        #[prost(uint64, tag = "1")]
1990        pub parallelism: u64,
1991    }
1992}
1993/// Schema change operation for sink
1994#[derive(prost_helpers::AnyPB)]
1995#[derive(Clone, PartialEq, ::prost::Message)]
1996pub struct SinkSchemaChange {
1997    /// Original schema before this change.
1998    /// Used for validation and conflict detection.
1999    #[prost(message, repeated, tag = "1")]
2000    pub original_schema: ::prost::alloc::vec::Vec<super::plan_common::Field>,
2001    /// Schema change operation (mutually exclusive)
2002    #[prost(oneof = "sink_schema_change::Op", tags = "2, 3")]
2003    pub op: ::core::option::Option<sink_schema_change::Op>,
2004}
2005/// Nested message and enum types in `SinkSchemaChange`.
2006pub mod sink_schema_change {
2007    /// Schema change operation (mutually exclusive)
2008    #[derive(prost_helpers::AnyPB)]
2009    #[derive(Clone, PartialEq, ::prost::Oneof)]
2010    pub enum Op {
2011        /// Add new columns to the schema
2012        #[prost(message, tag = "2")]
2013        AddColumns(super::SinkAddColumnsOp),
2014        /// Drop columns from the schema
2015        #[prost(message, tag = "3")]
2016        DropColumns(super::SinkDropColumnsOp),
2017    }
2018}
2019/// Add columns operation
2020#[derive(prost_helpers::AnyPB)]
2021#[derive(Clone, PartialEq, ::prost::Message)]
2022pub struct SinkAddColumnsOp {
2023    /// Columns to add
2024    #[prost(message, repeated, tag = "1")]
2025    pub fields: ::prost::alloc::vec::Vec<super::plan_common::Field>,
2026}
2027/// Drop columns operation
2028#[derive(prost_helpers::AnyPB)]
2029#[derive(Clone, PartialEq, ::prost::Message)]
2030pub struct SinkDropColumnsOp {
2031    /// Column names to drop
2032    #[prost(string, repeated, tag = "1")]
2033    pub column_names: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
2034}
2035#[derive(prost_helpers::AnyPB)]
2036#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2037#[repr(i32)]
2038pub enum SinkLogStoreType {
2039    /// / Default value is the normal in memory log store to be backward compatible with the previously unset value
2040    Unspecified = 0,
2041    KvLogStore = 1,
2042    InMemoryLogStore = 2,
2043}
2044impl SinkLogStoreType {
2045    /// String value of the enum field names used in the ProtoBuf definition.
2046    ///
2047    /// The values are not transformed in any way and thus are considered stable
2048    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2049    pub fn as_str_name(&self) -> &'static str {
2050        match self {
2051            Self::Unspecified => "SINK_LOG_STORE_TYPE_UNSPECIFIED",
2052            Self::KvLogStore => "SINK_LOG_STORE_TYPE_KV_LOG_STORE",
2053            Self::InMemoryLogStore => "SINK_LOG_STORE_TYPE_IN_MEMORY_LOG_STORE",
2054        }
2055    }
2056    /// Creates an enum from field names used in the ProtoBuf definition.
2057    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2058        match value {
2059            "SINK_LOG_STORE_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2060            "SINK_LOG_STORE_TYPE_KV_LOG_STORE" => Some(Self::KvLogStore),
2061            "SINK_LOG_STORE_TYPE_IN_MEMORY_LOG_STORE" => Some(Self::InMemoryLogStore),
2062            _ => None,
2063        }
2064    }
2065}
2066#[derive(prost_helpers::AnyPB)]
2067#[derive(prost_helpers::Version)]
2068#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2069#[repr(i32)]
2070pub enum AggNodeVersion {
2071    Unspecified = 0,
2072    /// <https://github.com/risingwavelabs/risingwave/issues/12140#issuecomment-1776289808>
2073    Issue12140 = 1,
2074    /// <https://github.com/risingwavelabs/risingwave/issues/13465#issuecomment-1821016508>
2075    Issue13465 = 2,
2076}
2077impl AggNodeVersion {
2078    /// String value of the enum field names used in the ProtoBuf definition.
2079    ///
2080    /// The values are not transformed in any way and thus are considered stable
2081    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2082    pub fn as_str_name(&self) -> &'static str {
2083        match self {
2084            Self::Unspecified => "AGG_NODE_VERSION_UNSPECIFIED",
2085            Self::Issue12140 => "AGG_NODE_VERSION_ISSUE_12140",
2086            Self::Issue13465 => "AGG_NODE_VERSION_ISSUE_13465",
2087        }
2088    }
2089    /// Creates an enum from field names used in the ProtoBuf definition.
2090    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2091        match value {
2092            "AGG_NODE_VERSION_UNSPECIFIED" => Some(Self::Unspecified),
2093            "AGG_NODE_VERSION_ISSUE_12140" => Some(Self::Issue12140),
2094            "AGG_NODE_VERSION_ISSUE_13465" => Some(Self::Issue13465),
2095            _ => None,
2096        }
2097    }
2098}
2099#[derive(prost_helpers::AnyPB)]
2100#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2101#[repr(i32)]
2102pub enum InequalityType {
2103    Unspecified = 0,
2104    LessThan = 1,
2105    LessThanOrEqual = 2,
2106    GreaterThan = 3,
2107    GreaterThanOrEqual = 4,
2108}
2109impl InequalityType {
2110    /// String value of the enum field names used in the ProtoBuf definition.
2111    ///
2112    /// The values are not transformed in any way and thus are considered stable
2113    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2114    pub fn as_str_name(&self) -> &'static str {
2115        match self {
2116            Self::Unspecified => "INEQUALITY_TYPE_UNSPECIFIED",
2117            Self::LessThan => "INEQUALITY_TYPE_LESS_THAN",
2118            Self::LessThanOrEqual => "INEQUALITY_TYPE_LESS_THAN_OR_EQUAL",
2119            Self::GreaterThan => "INEQUALITY_TYPE_GREATER_THAN",
2120            Self::GreaterThanOrEqual => "INEQUALITY_TYPE_GREATER_THAN_OR_EQUAL",
2121        }
2122    }
2123    /// Creates an enum from field names used in the ProtoBuf definition.
2124    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2125        match value {
2126            "INEQUALITY_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2127            "INEQUALITY_TYPE_LESS_THAN" => Some(Self::LessThan),
2128            "INEQUALITY_TYPE_LESS_THAN_OR_EQUAL" => Some(Self::LessThanOrEqual),
2129            "INEQUALITY_TYPE_GREATER_THAN" => Some(Self::GreaterThan),
2130            "INEQUALITY_TYPE_GREATER_THAN_OR_EQUAL" => Some(Self::GreaterThanOrEqual),
2131            _ => None,
2132        }
2133    }
2134}
2135#[derive(prost_helpers::AnyPB)]
2136#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2137#[repr(i32)]
2138pub enum JoinEncodingType {
2139    Unspecified = 0,
2140    MemoryOptimized = 1,
2141    CpuOptimized = 2,
2142}
2143impl JoinEncodingType {
2144    /// String value of the enum field names used in the ProtoBuf definition.
2145    ///
2146    /// The values are not transformed in any way and thus are considered stable
2147    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2148    pub fn as_str_name(&self) -> &'static str {
2149        match self {
2150            Self::Unspecified => "UNSPECIFIED",
2151            Self::MemoryOptimized => "MEMORY_OPTIMIZED",
2152            Self::CpuOptimized => "CPU_OPTIMIZED",
2153        }
2154    }
2155    /// Creates an enum from field names used in the ProtoBuf definition.
2156    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2157        match value {
2158            "UNSPECIFIED" => Some(Self::Unspecified),
2159            "MEMORY_OPTIMIZED" => Some(Self::MemoryOptimized),
2160            "CPU_OPTIMIZED" => Some(Self::CpuOptimized),
2161            _ => None,
2162        }
2163    }
2164}
2165/// Decides which kind of Executor will be used
2166#[derive(prost_helpers::AnyPB)]
2167#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2168#[repr(i32)]
2169pub enum StreamScanType {
2170    Unspecified = 0,
2171    /// ChainExecutor
2172    Chain = 1,
2173    /// RearrangedChainExecutor
2174    Rearrange = 2,
2175    /// BackfillExecutor
2176    Backfill = 3,
2177    /// ChainExecutor with upstream_only = true
2178    UpstreamOnly = 4,
2179    /// ArrangementBackfillExecutor
2180    ArrangementBackfill = 5,
2181    /// SnapshotBackfillExecutor
2182    SnapshotBackfill = 6,
2183    /// SnapshotBackfillExecutor
2184    CrossDbSnapshotBackfill = 7,
2185}
2186impl StreamScanType {
2187    /// String value of the enum field names used in the ProtoBuf definition.
2188    ///
2189    /// The values are not transformed in any way and thus are considered stable
2190    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2191    pub fn as_str_name(&self) -> &'static str {
2192        match self {
2193            Self::Unspecified => "STREAM_SCAN_TYPE_UNSPECIFIED",
2194            Self::Chain => "STREAM_SCAN_TYPE_CHAIN",
2195            Self::Rearrange => "STREAM_SCAN_TYPE_REARRANGE",
2196            Self::Backfill => "STREAM_SCAN_TYPE_BACKFILL",
2197            Self::UpstreamOnly => "STREAM_SCAN_TYPE_UPSTREAM_ONLY",
2198            Self::ArrangementBackfill => "STREAM_SCAN_TYPE_ARRANGEMENT_BACKFILL",
2199            Self::SnapshotBackfill => "STREAM_SCAN_TYPE_SNAPSHOT_BACKFILL",
2200            Self::CrossDbSnapshotBackfill => {
2201                "STREAM_SCAN_TYPE_CROSS_DB_SNAPSHOT_BACKFILL"
2202            }
2203        }
2204    }
2205    /// Creates an enum from field names used in the ProtoBuf definition.
2206    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2207        match value {
2208            "STREAM_SCAN_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2209            "STREAM_SCAN_TYPE_CHAIN" => Some(Self::Chain),
2210            "STREAM_SCAN_TYPE_REARRANGE" => Some(Self::Rearrange),
2211            "STREAM_SCAN_TYPE_BACKFILL" => Some(Self::Backfill),
2212            "STREAM_SCAN_TYPE_UPSTREAM_ONLY" => Some(Self::UpstreamOnly),
2213            "STREAM_SCAN_TYPE_ARRANGEMENT_BACKFILL" => Some(Self::ArrangementBackfill),
2214            "STREAM_SCAN_TYPE_SNAPSHOT_BACKFILL" => Some(Self::SnapshotBackfill),
2215            "STREAM_SCAN_TYPE_CROSS_DB_SNAPSHOT_BACKFILL" => {
2216                Some(Self::CrossDbSnapshotBackfill)
2217            }
2218            _ => None,
2219        }
2220    }
2221}
2222#[derive(prost_helpers::AnyPB)]
2223#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2224#[repr(i32)]
2225pub enum OverWindowCachePolicy {
2226    Unspecified = 0,
2227    Full = 1,
2228    Recent = 2,
2229    RecentFirstN = 3,
2230    RecentLastN = 4,
2231}
2232impl OverWindowCachePolicy {
2233    /// String value of the enum field names used in the ProtoBuf definition.
2234    ///
2235    /// The values are not transformed in any way and thus are considered stable
2236    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2237    pub fn as_str_name(&self) -> &'static str {
2238        match self {
2239            Self::Unspecified => "OVER_WINDOW_CACHE_POLICY_UNSPECIFIED",
2240            Self::Full => "OVER_WINDOW_CACHE_POLICY_FULL",
2241            Self::Recent => "OVER_WINDOW_CACHE_POLICY_RECENT",
2242            Self::RecentFirstN => "OVER_WINDOW_CACHE_POLICY_RECENT_FIRST_N",
2243            Self::RecentLastN => "OVER_WINDOW_CACHE_POLICY_RECENT_LAST_N",
2244        }
2245    }
2246    /// Creates an enum from field names used in the ProtoBuf definition.
2247    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2248        match value {
2249            "OVER_WINDOW_CACHE_POLICY_UNSPECIFIED" => Some(Self::Unspecified),
2250            "OVER_WINDOW_CACHE_POLICY_FULL" => Some(Self::Full),
2251            "OVER_WINDOW_CACHE_POLICY_RECENT" => Some(Self::Recent),
2252            "OVER_WINDOW_CACHE_POLICY_RECENT_FIRST_N" => Some(Self::RecentFirstN),
2253            "OVER_WINDOW_CACHE_POLICY_RECENT_LAST_N" => Some(Self::RecentLastN),
2254            _ => None,
2255        }
2256    }
2257}
2258#[derive(prost_helpers::AnyPB)]
2259#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
2260#[repr(i32)]
2261pub enum DispatcherType {
2262    Unspecified = 0,
2263    /// Dispatch by hash key, hashed by consistent hash.
2264    Hash = 1,
2265    /// Broadcast to all downstreams.
2266    ///
2267    /// Note a broadcast cannot be represented as multiple simple dispatchers, since they are
2268    /// different when we update dispatchers during scaling.
2269    Broadcast = 2,
2270    /// Only one downstream.
2271    Simple = 3,
2272    /// A special kind of exchange that doesn't involve shuffle. The upstream actor will be directly
2273    /// piped into the downstream actor, if there are the same number of actors. If number of actors
2274    /// are not the same, should use hash instead. Should be only used when distribution is the same.
2275    NoShuffle = 4,
2276}
2277impl DispatcherType {
2278    /// String value of the enum field names used in the ProtoBuf definition.
2279    ///
2280    /// The values are not transformed in any way and thus are considered stable
2281    /// (if the ProtoBuf definition does not change) and safe for programmatic use.
2282    pub fn as_str_name(&self) -> &'static str {
2283        match self {
2284            Self::Unspecified => "DISPATCHER_TYPE_UNSPECIFIED",
2285            Self::Hash => "DISPATCHER_TYPE_HASH",
2286            Self::Broadcast => "DISPATCHER_TYPE_BROADCAST",
2287            Self::Simple => "DISPATCHER_TYPE_SIMPLE",
2288            Self::NoShuffle => "DISPATCHER_TYPE_NO_SHUFFLE",
2289        }
2290    }
2291    /// Creates an enum from field names used in the ProtoBuf definition.
2292    pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
2293        match value {
2294            "DISPATCHER_TYPE_UNSPECIFIED" => Some(Self::Unspecified),
2295            "DISPATCHER_TYPE_HASH" => Some(Self::Hash),
2296            "DISPATCHER_TYPE_BROADCAST" => Some(Self::Broadcast),
2297            "DISPATCHER_TYPE_SIMPLE" => Some(Self::Simple),
2298            "DISPATCHER_TYPE_NO_SHUFFLE" => Some(Self::NoShuffle),
2299            _ => None,
2300        }
2301    }
2302}