spark-connect 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +82 -0
  3. data/LICENSE +202 -0
  4. data/NOTICE +16 -0
  5. data/README.md +166 -0
  6. data/lib/spark-connect.rb +5 -0
  7. data/lib/spark_connect/arrow.rb +115 -0
  8. data/lib/spark_connect/catalog.rb +190 -0
  9. data/lib/spark_connect/channel_builder.rb +134 -0
  10. data/lib/spark_connect/client.rb +264 -0
  11. data/lib/spark_connect/column.rb +379 -0
  12. data/lib/spark_connect/conf.rb +79 -0
  13. data/lib/spark_connect/data_frame.rb +828 -0
  14. data/lib/spark_connect/errors.rb +58 -0
  15. data/lib/spark_connect/functions.rb +903 -0
  16. data/lib/spark_connect/grouped_data.rb +101 -0
  17. data/lib/spark_connect/na_functions.rb +98 -0
  18. data/lib/spark_connect/observation.rb +61 -0
  19. data/lib/spark_connect/pipelines.rb +221 -0
  20. data/lib/spark_connect/plan.rb +39 -0
  21. data/lib/spark_connect/proto/spark/connect/base_pb.rb +118 -0
  22. data/lib/spark_connect/proto/spark/connect/base_services_pb.rb +82 -0
  23. data/lib/spark_connect/proto/spark/connect/catalog_pb.rb +46 -0
  24. data/lib/spark_connect/proto/spark/connect/commands_pb.rb +67 -0
  25. data/lib/spark_connect/proto/spark/connect/common_pb.rb +32 -0
  26. data/lib/spark_connect/proto/spark/connect/expressions_pb.rb +63 -0
  27. data/lib/spark_connect/proto/spark/connect/ml_common_pb.rb +22 -0
  28. data/lib/spark_connect/proto/spark/connect/ml_pb.rb +32 -0
  29. data/lib/spark_connect/proto/spark/connect/pipelines_pb.rb +45 -0
  30. data/lib/spark_connect/proto/spark/connect/relations_pb.rb +102 -0
  31. data/lib/spark_connect/proto/spark/connect/types_pb.rb +46 -0
  32. data/lib/spark_connect/proto.rb +32 -0
  33. data/lib/spark_connect/reader.rb +98 -0
  34. data/lib/spark_connect/row.rb +105 -0
  35. data/lib/spark_connect/session.rb +317 -0
  36. data/lib/spark_connect/stat_functions.rb +109 -0
  37. data/lib/spark_connect/streaming.rb +351 -0
  38. data/lib/spark_connect/types.rb +490 -0
  39. data/lib/spark_connect/version.rb +11 -0
  40. data/lib/spark_connect/window.rb +119 -0
  41. data/lib/spark_connect/writer.rb +208 -0
  42. data/lib/spark_connect.rb +58 -0
  43. data/proto/spark/connect/base.proto +1275 -0
  44. data/proto/spark/connect/catalog.proto +243 -0
  45. data/proto/spark/connect/commands.proto +553 -0
  46. data/proto/spark/connect/common.proto +179 -0
  47. data/proto/spark/connect/expressions.proto +557 -0
  48. data/proto/spark/connect/ml.proto +147 -0
  49. data/proto/spark/connect/ml_common.proto +64 -0
  50. data/proto/spark/connect/pipelines.proto +307 -0
  51. data/proto/spark/connect/relations.proto +1252 -0
  52. data/proto/spark/connect/types.proto +227 -0
  53. metadata +149 -0
@@ -0,0 +1,1252 @@
1
+ /*
2
+ * Licensed to the Apache Software Foundation (ASF) under one or more
3
+ * contributor license agreements. See the NOTICE file distributed with
4
+ * this work for additional information regarding copyright ownership.
5
+ * The ASF licenses this file to You under the Apache License, Version 2.0
6
+ * (the "License"); you may not use this file except in compliance with
7
+ * the License. You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ syntax = 'proto3';
19
+
20
+ package spark.connect;
21
+
22
+ import "google/protobuf/any.proto";
23
+ import "spark/connect/expressions.proto";
24
+ import "spark/connect/types.proto";
25
+ import "spark/connect/catalog.proto";
26
+ import "spark/connect/common.proto";
27
+ import "spark/connect/ml_common.proto";
28
+
29
+ option java_multiple_files = true;
30
+ option java_package = "org.apache.spark.connect.proto";
31
+ option go_package = "internal/generated";
32
+
33
+ // The main [[Relation]] type. Fundamentally, a relation is a typed container
34
+ // that has exactly one explicit relation type set.
35
+ //
36
+ // When adding new relation types, they have to be registered here.
37
+ message Relation {
38
+ RelationCommon common = 1;
39
+ oneof rel_type {
40
+ Read read = 2;
41
+ Project project = 3;
42
+ Filter filter = 4;
43
+ Join join = 5;
44
+ SetOperation set_op = 6;
45
+ Sort sort = 7;
46
+ Limit limit = 8;
47
+ Aggregate aggregate = 9;
48
+ SQL sql = 10;
49
+ LocalRelation local_relation = 11;
50
+ Sample sample = 12;
51
+ Offset offset = 13;
52
+ Deduplicate deduplicate = 14;
53
+ Range range = 15;
54
+ SubqueryAlias subquery_alias = 16;
55
+ Repartition repartition = 17;
56
+ ToDF to_df = 18;
57
+ WithColumnsRenamed with_columns_renamed = 19;
58
+ ShowString show_string = 20;
59
+ Drop drop = 21;
60
+ Tail tail = 22;
61
+ WithColumns with_columns = 23;
62
+ Hint hint = 24;
63
+ Unpivot unpivot = 25;
64
+ ToSchema to_schema = 26;
65
+ RepartitionByExpression repartition_by_expression = 27;
66
+ MapPartitions map_partitions = 28;
67
+ CollectMetrics collect_metrics = 29;
68
+ Parse parse = 30;
69
+ GroupMap group_map = 31;
70
+ CoGroupMap co_group_map = 32;
71
+ WithWatermark with_watermark = 33;
72
+ ApplyInPandasWithState apply_in_pandas_with_state = 34;
73
+ HtmlString html_string = 35;
74
+ CachedLocalRelation cached_local_relation = 36;
75
+ CachedRemoteRelation cached_remote_relation = 37;
76
+ CommonInlineUserDefinedTableFunction common_inline_user_defined_table_function = 38;
77
+ AsOfJoin as_of_join = 39;
78
+ CommonInlineUserDefinedDataSource common_inline_user_defined_data_source = 40;
79
+ WithRelations with_relations = 41;
80
+ Transpose transpose = 42;
81
+ UnresolvedTableValuedFunction unresolved_table_valued_function = 43;
82
+ LateralJoin lateral_join = 44;
83
+ ChunkedCachedLocalRelation chunked_cached_local_relation = 45;
84
+
85
+ // NA functions
86
+ NAFill fill_na = 90;
87
+ NADrop drop_na = 91;
88
+ NAReplace replace = 92;
89
+
90
+ // stat functions
91
+ StatSummary summary = 100;
92
+ StatCrosstab crosstab = 101;
93
+ StatDescribe describe = 102;
94
+ StatCov cov = 103;
95
+ StatCorr corr = 104;
96
+ StatApproxQuantile approx_quantile = 105;
97
+ StatFreqItems freq_items = 106;
98
+ StatSampleBy sample_by = 107;
99
+
100
+ // Catalog API (experimental / unstable)
101
+ Catalog catalog = 200;
102
+
103
+ // ML relation
104
+ MlRelation ml_relation = 300;
105
+
106
+ // This field is used to mark extensions to the protocol. When plugins generate arbitrary
107
+ // relations they can add them here. During the planning the correct resolution is done.
108
+ google.protobuf.Any extension = 998;
109
+ Unknown unknown = 999;
110
+ }
111
+ }
112
+
113
+ // Relation to represent ML world
114
+ message MlRelation {
115
+ oneof ml_type {
116
+ Transform transform = 1;
117
+ Fetch fetch = 2;
118
+ }
119
+ // (Optional) the dataset for restoring the model summary
120
+ optional Relation model_summary_dataset = 3;
121
+
122
+ // Relation to represent transform(input) of the operator
123
+ // which could be a cached model or a new transformer
124
+ message Transform {
125
+ oneof operator {
126
+ // Object reference
127
+ ObjectRef obj_ref = 1;
128
+ // Could be an ML transformer like VectorAssembler
129
+ MlOperator transformer = 2;
130
+ }
131
+ // the input dataframe
132
+ Relation input = 3;
133
+ // the operator specific parameters
134
+ MlParams params = 4;
135
+ }
136
+ }
137
+
138
+ // Message for fetching attribute from object on the server side.
139
+ // Fetch can be represented as a Relation or a ML command
140
+ // Command: model.coefficients, model.summary.weightedPrecision which
141
+ // returns the final literal result
142
+ // Relation: model.summary.roc which returns a DataFrame (Relation)
143
+ message Fetch {
144
+ // (Required) reference to the object on the server side
145
+ ObjectRef obj_ref = 1;
146
+ // (Required) the calling method chains
147
+ repeated Method methods = 2;
148
+
149
+ // Represents a method with inclusion of method name and its arguments
150
+ message Method {
151
+ // (Required) the method name
152
+ string method = 1;
153
+ // (Optional) the arguments of the method
154
+ repeated Args args = 2;
155
+
156
+ message Args {
157
+ oneof args_type {
158
+ Expression.Literal param = 1;
159
+ Relation input = 2;
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ // Used for testing purposes only.
166
+ message Unknown {}
167
+
168
+ // Common metadata of all relations.
169
+ message RelationCommon {
170
+ // (Required) Shared relation metadata.
171
+ string source_info = 1 [deprecated=true];
172
+
173
+ // (Optional) A per-client globally unique id for a given connect plan.
174
+ optional int64 plan_id = 2;
175
+
176
+ // (Optional) Keep the information of the origin for this expression such as stacktrace.
177
+ Origin origin = 3;
178
+ }
179
+
180
+ // Relation that uses a SQL query to generate the output.
181
+ message SQL {
182
+ // (Required) The SQL query.
183
+ string query = 1;
184
+
185
+ // (Optional) A map of parameter names to literal expressions.
186
+ map<string, Expression.Literal> args = 2 [deprecated=true];
187
+
188
+ // (Optional) A sequence of literal expressions for positional parameters in the SQL query text.
189
+ repeated Expression.Literal pos_args = 3 [deprecated=true];
190
+
191
+ // (Optional) A map of parameter names to expressions.
192
+ // It cannot coexist with `pos_arguments`.
193
+ map<string, Expression> named_arguments = 4;
194
+
195
+ // (Optional) A sequence of expressions for positional parameters in the SQL query text.
196
+ // It cannot coexist with `named_arguments`.
197
+ repeated Expression pos_arguments = 5;
198
+ }
199
+
200
+ // Relation of type [[WithRelations]].
201
+ //
202
+ // This relation contains a root plan, and one or more references that are used by the root plan.
203
+ // There are two ways of referencing a relation, by name (through a subquery alias), or by plan_id
204
+ // (using RelationCommon.plan_id).
205
+ //
206
+ // This relation can be used to implement CTEs, describe DAGs, or to reduce tree depth.
207
+ message WithRelations {
208
+ // (Required) Plan at the root of the query tree. This plan is expected to contain one or more
209
+ // references. Those references get expanded later on by the engine.
210
+ Relation root = 1;
211
+
212
+ // (Required) Plans referenced by the root plan. Relations in this list are also allowed to
213
+ // contain references to other relations in this list, as long they do not form cycles.
214
+ repeated Relation references = 2;
215
+ }
216
+
217
+ // Relation that reads from a file / table or other data source. Does not have additional
218
+ // inputs.
219
+ message Read {
220
+ oneof read_type {
221
+ NamedTable named_table = 1;
222
+ DataSource data_source = 2;
223
+ }
224
+
225
+ // (Optional) Indicates if this is a streaming read.
226
+ bool is_streaming = 3;
227
+
228
+ message NamedTable {
229
+ // (Required) Unparsed identifier for the table.
230
+ string unparsed_identifier = 1;
231
+
232
+ // Options for the named table. The map key is case insensitive.
233
+ map<string, string> options = 2;
234
+ }
235
+
236
+ message DataSource {
237
+ // (Optional) Supported formats include: parquet, orc, text, json, parquet, csv, avro.
238
+ //
239
+ // If not set, the value from SQL conf 'spark.sql.sources.default' will be used.
240
+ optional string format = 1;
241
+
242
+ // (Optional) If not set, Spark will infer the schema.
243
+ //
244
+ // This schema string should be either DDL-formatted or JSON-formatted.
245
+ optional string schema = 2;
246
+
247
+ // Options for the data source. The context of this map varies based on the
248
+ // data source format. This options could be empty for valid data source format.
249
+ // The map key is case insensitive.
250
+ map<string, string> options = 3;
251
+
252
+ // (Optional) A list of path for file-system backed data sources.
253
+ repeated string paths = 4;
254
+
255
+ // (Optional) Condition in the where clause for each partition.
256
+ //
257
+ // This is only supported by the JDBC data source.
258
+ repeated string predicates = 5;
259
+ }
260
+ }
261
+
262
+ // Projection of a bag of expressions for a given input relation.
263
+ //
264
+ // The input relation must be specified.
265
+ // The projected expression can be an arbitrary expression.
266
+ message Project {
267
+ // (Optional) Input relation is optional for Project.
268
+ //
269
+ // For example, `SELECT ABS(-1)` is valid plan without an input plan.
270
+ Relation input = 1;
271
+
272
+ // (Required) A Project requires at least one expression.
273
+ repeated Expression expressions = 3;
274
+ }
275
+
276
+ // Relation that applies a boolean expression `condition` on each row of `input` to produce
277
+ // the output result.
278
+ message Filter {
279
+ // (Required) Input relation for a Filter.
280
+ Relation input = 1;
281
+
282
+ // (Required) A Filter must have a condition expression.
283
+ Expression condition = 2;
284
+ }
285
+
286
+ // Relation of type [[Join]].
287
+ //
288
+ // `left` and `right` must be present.
289
+ message Join {
290
+ // (Required) Left input relation for a Join.
291
+ Relation left = 1;
292
+
293
+ // (Required) Right input relation for a Join.
294
+ Relation right = 2;
295
+
296
+ // (Optional) The join condition. Could be unset when `using_columns` is utilized.
297
+ //
298
+ // This field does not co-exist with using_columns.
299
+ Expression join_condition = 3;
300
+
301
+ // (Required) The join type.
302
+ JoinType join_type = 4;
303
+
304
+ // Optional. using_columns provides a list of columns that should present on both sides of
305
+ // the join inputs that this Join will join on. For example A JOIN B USING col_name is
306
+ // equivalent to A JOIN B on A.col_name = B.col_name.
307
+ //
308
+ // This field does not co-exist with join_condition.
309
+ repeated string using_columns = 5;
310
+
311
+ enum JoinType {
312
+ JOIN_TYPE_UNSPECIFIED = 0;
313
+ JOIN_TYPE_INNER = 1;
314
+ JOIN_TYPE_FULL_OUTER = 2;
315
+ JOIN_TYPE_LEFT_OUTER = 3;
316
+ JOIN_TYPE_RIGHT_OUTER = 4;
317
+ JOIN_TYPE_LEFT_ANTI = 5;
318
+ JOIN_TYPE_LEFT_SEMI = 6;
319
+ JOIN_TYPE_CROSS = 7;
320
+ }
321
+
322
+ // (Optional) Only used by joinWith. Set the left and right join data types.
323
+ optional JoinDataType join_data_type = 6;
324
+
325
+ message JoinDataType {
326
+ // If the left data type is a struct.
327
+ bool is_left_struct = 1;
328
+ // If the right data type is a struct.
329
+ bool is_right_struct = 2;
330
+ }
331
+ }
332
+
333
+ // Relation of type [[SetOperation]]
334
+ message SetOperation {
335
+ // (Required) Left input relation for a Set operation.
336
+ Relation left_input = 1;
337
+
338
+ // (Required) Right input relation for a Set operation.
339
+ Relation right_input = 2;
340
+
341
+ // (Required) The Set operation type.
342
+ SetOpType set_op_type = 3;
343
+
344
+ // (Optional) If to remove duplicate rows.
345
+ //
346
+ // True to preserve all results.
347
+ // False to remove duplicate rows.
348
+ optional bool is_all = 4;
349
+
350
+ // (Optional) If to perform the Set operation based on name resolution.
351
+ //
352
+ // Only UNION supports this option.
353
+ optional bool by_name = 5;
354
+
355
+ // (Optional) If to perform the Set operation and allow missing columns.
356
+ //
357
+ // Only UNION supports this option.
358
+ optional bool allow_missing_columns = 6;
359
+
360
+ enum SetOpType {
361
+ SET_OP_TYPE_UNSPECIFIED = 0;
362
+ SET_OP_TYPE_INTERSECT = 1;
363
+ SET_OP_TYPE_UNION = 2;
364
+ SET_OP_TYPE_EXCEPT = 3;
365
+ }
366
+ }
367
+
368
+ // Relation of type [[Limit]] that is used to `limit` rows from the input relation.
369
+ message Limit {
370
+ // (Required) Input relation for a Limit.
371
+ Relation input = 1;
372
+
373
+ // (Required) the limit.
374
+ int32 limit = 2;
375
+ }
376
+
377
+ // Relation of type [[Offset]] that is used to read rows staring from the `offset` on
378
+ // the input relation.
379
+ message Offset {
380
+ // (Required) Input relation for an Offset.
381
+ Relation input = 1;
382
+
383
+ // (Required) the limit.
384
+ int32 offset = 2;
385
+ }
386
+
387
+ // Relation of type [[Tail]] that is used to fetch `limit` rows from the last of the input relation.
388
+ message Tail {
389
+ // (Required) Input relation for an Tail.
390
+ Relation input = 1;
391
+
392
+ // (Required) the limit.
393
+ int32 limit = 2;
394
+ }
395
+
396
+ // Relation of type [[Aggregate]].
397
+ message Aggregate {
398
+ // (Required) Input relation for a RelationalGroupedDataset.
399
+ Relation input = 1;
400
+
401
+ // (Required) How the RelationalGroupedDataset was built.
402
+ GroupType group_type = 2;
403
+
404
+ // (Required) Expressions for grouping keys
405
+ repeated Expression grouping_expressions = 3;
406
+
407
+ // (Required) List of values that will be translated to columns in the output DataFrame.
408
+ repeated Expression aggregate_expressions = 4;
409
+
410
+ // (Optional) Pivots a column of the current `DataFrame` and performs the specified aggregation.
411
+ Pivot pivot = 5;
412
+
413
+ // (Optional) List of values that will be translated to columns in the output DataFrame.
414
+ repeated GroupingSets grouping_sets = 6;
415
+
416
+ enum GroupType {
417
+ GROUP_TYPE_UNSPECIFIED = 0;
418
+ GROUP_TYPE_GROUPBY = 1;
419
+ GROUP_TYPE_ROLLUP = 2;
420
+ GROUP_TYPE_CUBE = 3;
421
+ GROUP_TYPE_PIVOT = 4;
422
+ GROUP_TYPE_GROUPING_SETS = 5;
423
+ }
424
+
425
+ message Pivot {
426
+ // (Required) The column to pivot
427
+ Expression col = 1;
428
+
429
+ // (Optional) List of values that will be translated to columns in the output DataFrame.
430
+ //
431
+ // Note that if it is empty, the server side will immediately trigger a job to collect
432
+ // the distinct values of the column.
433
+ repeated Expression.Literal values = 2;
434
+ }
435
+
436
+ message GroupingSets {
437
+ // (Required) Individual grouping set
438
+ repeated Expression grouping_set = 1;
439
+ }
440
+ }
441
+
442
+ // Relation of type [[Sort]].
443
+ message Sort {
444
+ // (Required) Input relation for a Sort.
445
+ Relation input = 1;
446
+
447
+ // (Required) The ordering expressions
448
+ repeated Expression.SortOrder order = 2;
449
+
450
+ // (Optional) if this is a global sort.
451
+ optional bool is_global = 3;
452
+ }
453
+
454
+
455
+ // Drop specified columns.
456
+ message Drop {
457
+ // (Required) The input relation.
458
+ Relation input = 1;
459
+
460
+ // (Optional) columns to drop.
461
+ repeated Expression columns = 2;
462
+
463
+ // (Optional) names of columns to drop.
464
+ repeated string column_names = 3;
465
+ }
466
+
467
+
468
+ // Relation of type [[Deduplicate]] which have duplicate rows removed, could consider either only
469
+ // the subset of columns or all the columns.
470
+ message Deduplicate {
471
+ // (Required) Input relation for a Deduplicate.
472
+ Relation input = 1;
473
+
474
+ // (Optional) Deduplicate based on a list of column names.
475
+ //
476
+ // This field does not co-use with `all_columns_as_keys`.
477
+ repeated string column_names = 2;
478
+
479
+ // (Optional) Deduplicate based on all the columns of the input relation.
480
+ //
481
+ // This field does not co-use with `column_names`.
482
+ optional bool all_columns_as_keys = 3;
483
+
484
+ // (Optional) Deduplicate within the time range of watermark.
485
+ optional bool within_watermark = 4;
486
+ }
487
+
488
+ // A relation that does not need to be qualified by name.
489
+ message LocalRelation {
490
+ // (Optional) Local collection data serialized into Arrow IPC streaming format which contains
491
+ // the schema of the data.
492
+ optional bytes data = 1;
493
+
494
+ // (Optional) The schema of local data.
495
+ // It should be either a DDL-formatted type string or a JSON string.
496
+ //
497
+ // The server side will update the column names and data types according to this schema.
498
+ // If the 'data' is not provided, then this schema will be required.
499
+ optional string schema = 2;
500
+ }
501
+
502
+ // A local relation that has been cached already.
503
+ // CachedLocalRelation doesn't support LocalRelations of size over 2GB.
504
+ message CachedLocalRelation {
505
+ // `userId` and `sessionId` fields are deleted since the server must always use the active
506
+ // session/user rather than arbitrary values provided by the client. It is never valid to access
507
+ // a local relation from a different session/user.
508
+ reserved 1, 2;
509
+ reserved "userId", "sessionId";
510
+
511
+ // (Required) A sha-256 hash of the serialized local relation in proto, see LocalRelation.
512
+ string hash = 3;
513
+ }
514
+
515
+ // A local relation that has been cached already.
516
+ message ChunkedCachedLocalRelation {
517
+ // (Required) A list of sha-256 hashes for representing LocalRelation.data.
518
+ // Data is serialized in Arrow IPC streaming format, each batch is cached on the server as
519
+ // a separate artifact. Each hash represents one batch stored on the server.
520
+ // Hashes are hex-encoded strings (e.g., "a3b2c1d4...").
521
+ repeated string dataHashes = 1;
522
+
523
+ // (Optional) A sha-256 hash of the serialized LocalRelation.schema.
524
+ // Scala clients always provide the schema, Python clients can omit it.
525
+ // Hash is a hex-encoded string (e.g., "a3b2c1d4...").
526
+ optional string schemaHash = 2;
527
+ }
528
+
529
+ // Represents a remote relation that has been cached on server.
530
+ message CachedRemoteRelation {
531
+ // (Required) ID of the remote related (assigned by the service).
532
+ string relation_id = 1;
533
+ }
534
+
535
+ // Relation of type [[Sample]] that samples a fraction of the dataset.
536
+ message Sample {
537
+ // (Required) Input relation for a Sample.
538
+ Relation input = 1;
539
+
540
+ // (Required) lower bound.
541
+ double lower_bound = 2;
542
+
543
+ // (Required) upper bound.
544
+ double upper_bound = 3;
545
+
546
+ // (Optional) Whether to sample with replacement.
547
+ optional bool with_replacement = 4;
548
+
549
+ // (Required) The random seed.
550
+ // This field is required to avoid generating mutable dataframes (see SPARK-48184 for details),
551
+ // however, still keep it 'optional' here for backward compatibility.
552
+ optional int64 seed = 5;
553
+
554
+ // (Required) Explicitly sort the underlying plan to make the ordering deterministic or cache it.
555
+ // This flag is true when invoking `dataframe.randomSplit` to randomly splits DataFrame with the
556
+ // provided weights. Otherwise, it is false.
557
+ bool deterministic_order = 6;
558
+ }
559
+
560
+ // Relation of type [[Range]] that generates a sequence of integers.
561
+ message Range {
562
+ // (Optional) Default value = 0
563
+ optional int64 start = 1;
564
+
565
+ // (Required)
566
+ int64 end = 2;
567
+
568
+ // (Required)
569
+ int64 step = 3;
570
+
571
+ // Optional. Default value is assigned by 1) SQL conf "spark.sql.leafNodeDefaultParallelism" if
572
+ // it is set, or 2) spark default parallelism.
573
+ optional int32 num_partitions = 4;
574
+ }
575
+
576
+ // Relation alias.
577
+ message SubqueryAlias {
578
+ // (Required) The input relation of SubqueryAlias.
579
+ Relation input = 1;
580
+
581
+ // (Required) The alias.
582
+ string alias = 2;
583
+
584
+ // (Optional) Qualifier of the alias.
585
+ repeated string qualifier = 3;
586
+ }
587
+
588
+ // Relation repartition.
589
+ message Repartition {
590
+ // (Required) The input relation of Repartition.
591
+ Relation input = 1;
592
+
593
+ // (Required) Must be positive.
594
+ int32 num_partitions = 2;
595
+
596
+ // (Optional) Default value is false.
597
+ optional bool shuffle = 3;
598
+ }
599
+
600
+ // Compose the string representing rows for output.
601
+ // It will invoke 'Dataset.showString' to compute the results.
602
+ message ShowString {
603
+ // (Required) The input relation.
604
+ Relation input = 1;
605
+
606
+ // (Required) Number of rows to show.
607
+ int32 num_rows = 2;
608
+
609
+ // (Required) If set to more than 0, truncates strings to
610
+ // `truncate` characters and all cells will be aligned right.
611
+ int32 truncate = 3;
612
+
613
+ // (Required) If set to true, prints output rows vertically (one line per column value).
614
+ bool vertical = 4;
615
+ }
616
+
617
+ // Compose the string representing rows for output.
618
+ // It will invoke 'Dataset.htmlString' to compute the results.
619
+ message HtmlString {
620
+ // (Required) The input relation.
621
+ Relation input = 1;
622
+
623
+ // (Required) Number of rows to show.
624
+ int32 num_rows = 2;
625
+
626
+ // (Required) If set to more than 0, truncates strings to
627
+ // `truncate` characters and all cells will be aligned right.
628
+ int32 truncate = 3;
629
+ }
630
+
631
+ // Computes specified statistics for numeric and string columns.
632
+ // It will invoke 'Dataset.summary' (same as 'StatFunctions.summary')
633
+ // to compute the results.
634
+ message StatSummary {
635
+ // (Required) The input relation.
636
+ Relation input = 1;
637
+
638
+ // (Optional) Statistics from to be computed.
639
+ //
640
+ // Available statistics are:
641
+ // count
642
+ // mean
643
+ // stddev
644
+ // min
645
+ // max
646
+ // arbitrary approximate percentiles specified as a percentage (e.g. 75%)
647
+ // count_distinct
648
+ // approx_count_distinct
649
+ //
650
+ // If no statistics are given, this function computes 'count', 'mean', 'stddev', 'min',
651
+ // 'approximate quartiles' (percentiles at 25%, 50%, and 75%), and 'max'.
652
+ repeated string statistics = 2;
653
+ }
654
+
655
+ // Computes basic statistics for numeric and string columns, including count, mean, stddev, min,
656
+ // and max. If no columns are given, this function computes statistics for all numerical or
657
+ // string columns.
658
+ message StatDescribe {
659
+ // (Required) The input relation.
660
+ Relation input = 1;
661
+
662
+ // (Optional) Columns to compute statistics on.
663
+ repeated string cols = 2;
664
+ }
665
+
666
+ // Computes a pair-wise frequency table of the given columns. Also known as a contingency table.
667
+ // It will invoke 'Dataset.stat.crosstab' (same as 'StatFunctions.crossTabulate')
668
+ // to compute the results.
669
+ message StatCrosstab {
670
+ // (Required) The input relation.
671
+ Relation input = 1;
672
+
673
+ // (Required) The name of the first column.
674
+ //
675
+ // Distinct items will make the first item of each row.
676
+ string col1 = 2;
677
+
678
+ // (Required) The name of the second column.
679
+ //
680
+ // Distinct items will make the column names of the DataFrame.
681
+ string col2 = 3;
682
+ }
683
+
684
+ // Calculate the sample covariance of two numerical columns of a DataFrame.
685
+ // It will invoke 'Dataset.stat.cov' (same as 'StatFunctions.calculateCov') to compute the results.
686
+ message StatCov {
687
+ // (Required) The input relation.
688
+ Relation input = 1;
689
+
690
+ // (Required) The name of the first column.
691
+ string col1 = 2;
692
+
693
+ // (Required) The name of the second column.
694
+ string col2 = 3;
695
+ }
696
+
697
+ // Calculates the correlation of two columns of a DataFrame. Currently only supports the Pearson
698
+ // Correlation Coefficient. It will invoke 'Dataset.stat.corr' (same as
699
+ // 'StatFunctions.pearsonCorrelation') to compute the results.
700
+ message StatCorr {
701
+ // (Required) The input relation.
702
+ Relation input = 1;
703
+
704
+ // (Required) The name of the first column.
705
+ string col1 = 2;
706
+
707
+ // (Required) The name of the second column.
708
+ string col2 = 3;
709
+
710
+ // (Optional) Default value is 'pearson'.
711
+ //
712
+ // Currently only supports the Pearson Correlation Coefficient.
713
+ optional string method = 4;
714
+ }
715
+
716
+ // Calculates the approximate quantiles of numerical columns of a DataFrame.
717
+ // It will invoke 'Dataset.stat.approxQuantile' (same as 'StatFunctions.approxQuantile')
718
+ // to compute the results.
719
+ message StatApproxQuantile {
720
+ // (Required) The input relation.
721
+ Relation input = 1;
722
+
723
+ // (Required) The names of the numerical columns.
724
+ repeated string cols = 2;
725
+
726
+ // (Required) A list of quantile probabilities.
727
+ //
728
+ // Each number must belong to [0, 1].
729
+ // For example 0 is the minimum, 0.5 is the median, 1 is the maximum.
730
+ repeated double probabilities = 3;
731
+
732
+ // (Required) The relative target precision to achieve (greater than or equal to 0).
733
+ //
734
+ // If set to zero, the exact quantiles are computed, which could be very expensive.
735
+ // Note that values greater than 1 are accepted but give the same result as 1.
736
+ double relative_error = 4;
737
+ }
738
+
739
+ // Finding frequent items for columns, possibly with false positives.
740
+ // It will invoke 'Dataset.stat.freqItems' (same as 'StatFunctions.freqItems')
741
+ // to compute the results.
742
+ message StatFreqItems {
743
+ // (Required) The input relation.
744
+ Relation input = 1;
745
+
746
+ // (Required) The names of the columns to search frequent items in.
747
+ repeated string cols = 2;
748
+
749
+ // (Optional) The minimum frequency for an item to be considered `frequent`.
750
+ // Should be greater than 1e-4.
751
+ optional double support = 3;
752
+ }
753
+
754
+
755
+ // Returns a stratified sample without replacement based on the fraction
756
+ // given on each stratum.
757
+ // It will invoke 'Dataset.stat.freqItems' (same as 'StatFunctions.freqItems')
758
+ // to compute the results.
759
+ message StatSampleBy {
760
+ // (Required) The input relation.
761
+ Relation input = 1;
762
+
763
+ // (Required) The column that defines strata.
764
+ Expression col = 2;
765
+
766
+ // (Required) Sampling fraction for each stratum.
767
+ //
768
+ // If a stratum is not specified, we treat its fraction as zero.
769
+ repeated Fraction fractions = 3;
770
+
771
+ // (Required) The random seed.
772
+ // This field is required to avoid generating mutable dataframes (see SPARK-48184 for details),
773
+ // however, still keep it 'optional' here for backward compatibility.
774
+ optional int64 seed = 5;
775
+
776
+ message Fraction {
777
+ // (Required) The stratum.
778
+ Expression.Literal stratum = 1;
779
+
780
+ // (Required) The fraction value. Must be in [0, 1].
781
+ double fraction = 2;
782
+ }
783
+ }
784
+
785
+
786
+ // Replaces null values.
787
+ // It will invoke 'Dataset.na.fill' (same as 'DataFrameNaFunctions.fill') to compute the results.
788
+ // Following 3 parameter combinations are supported:
789
+ // 1, 'values' only contains 1 item, 'cols' is empty:
790
+ // replaces null values in all type-compatible columns.
791
+ // 2, 'values' only contains 1 item, 'cols' is not empty:
792
+ // replaces null values in specified columns.
793
+ // 3, 'values' contains more than 1 items, then 'cols' is required to have the same length:
794
+ // replaces each specified column with corresponding value.
795
+ message NAFill {
796
+ // (Required) The input relation.
797
+ Relation input = 1;
798
+
799
+ // (Optional) Optional list of column names to consider.
800
+ repeated string cols = 2;
801
+
802
+ // (Required) Values to replace null values with.
803
+ //
804
+ // Should contain at least 1 item.
805
+ // Only 4 data types are supported now: bool, long, double, string
806
+ repeated Expression.Literal values = 3;
807
+ }
808
+
809
+
810
+ // Drop rows containing null values.
811
+ // It will invoke 'Dataset.na.drop' (same as 'DataFrameNaFunctions.drop') to compute the results.
812
+ message NADrop {
813
+ // (Required) The input relation.
814
+ Relation input = 1;
815
+
816
+ // (Optional) Optional list of column names to consider.
817
+ //
818
+ // When it is empty, all the columns in the input relation will be considered.
819
+ repeated string cols = 2;
820
+
821
+ // (Optional) The minimum number of non-null and non-NaN values required to keep.
822
+ //
823
+ // When not set, it is equivalent to the number of considered columns, which means
824
+ // a row will be kept only if all columns are non-null.
825
+ //
826
+ // 'how' options ('all', 'any') can be easily converted to this field:
827
+ // - 'all' -> set 'min_non_nulls' 1;
828
+ // - 'any' -> keep 'min_non_nulls' unset;
829
+ optional int32 min_non_nulls = 3;
830
+ }
831
+
832
+
833
+ // Replaces old values with the corresponding values.
834
+ // It will invoke 'Dataset.na.replace' (same as 'DataFrameNaFunctions.replace')
835
+ // to compute the results.
836
+ message NAReplace {
837
+ // (Required) The input relation.
838
+ Relation input = 1;
839
+
840
+ // (Optional) List of column names to consider.
841
+ //
842
+ // When it is empty, all the type-compatible columns in the input relation will be considered.
843
+ repeated string cols = 2;
844
+
845
+ // (Optional) The value replacement mapping.
846
+ repeated Replacement replacements = 3;
847
+
848
+ message Replacement {
849
+ // (Required) The old value.
850
+ //
851
+ // Only 4 data types are supported now: null, bool, double, string.
852
+ Expression.Literal old_value = 1;
853
+
854
+ // (Required) The new value.
855
+ //
856
+ // Should be of the same data type with the old value.
857
+ Expression.Literal new_value = 2;
858
+ }
859
+ }
860
+
861
+
862
+ // Rename columns on the input relation by the same length of names.
863
+ message ToDF {
864
+ // (Required) The input relation of RenameColumnsBySameLengthNames.
865
+ Relation input = 1;
866
+
867
+ // (Required)
868
+ //
869
+ // The number of columns of the input relation must be equal to the length
870
+ // of this field. If this is not true, an exception will be returned.
871
+ repeated string column_names = 2;
872
+ }
873
+
874
+
875
+ // Rename columns on the input relation by a map with name to name mapping.
876
+ message WithColumnsRenamed {
877
+ // (Required) The input relation.
878
+ Relation input = 1;
879
+
880
+
881
+ // (Optional)
882
+ //
883
+ // Renaming column names of input relation from A to B where A is the map key
884
+ // and B is the map value. This is a no-op if schema doesn't contain any A. It
885
+ // does not require that all input relation column names to present as keys.
886
+ // duplicated B are not allowed.
887
+ map<string, string> rename_columns_map = 2 [deprecated=true];
888
+
889
+ repeated Rename renames = 3;
890
+
891
+ message Rename {
892
+ // (Required) The existing column name.
893
+ string col_name = 1;
894
+
895
+ // (Required) The new column name.
896
+ string new_col_name = 2;
897
+ }
898
+ }
899
+
900
+ // Adding columns or replacing the existing columns that have the same names.
901
+ message WithColumns {
902
+ // (Required) The input relation.
903
+ Relation input = 1;
904
+
905
+ // (Required)
906
+ //
907
+ // Given a column name, apply the corresponding expression on the column. If column
908
+ // name exists in the input relation, then replace the column. If the column name
909
+ // does not exist in the input relation, then adds it as a new column.
910
+ //
911
+ // Only one name part is expected from each Expression.Alias.
912
+ //
913
+ // An exception is thrown when duplicated names are present in the mapping.
914
+ repeated Expression.Alias aliases = 2;
915
+ }
916
+
917
+ message WithWatermark {
918
+
919
+ // (Required) The input relation
920
+ Relation input = 1;
921
+
922
+ // (Required) Name of the column containing event time.
923
+ string event_time = 2;
924
+
925
+ // (Required)
926
+ string delay_threshold = 3;
927
+ }
928
+
929
+ // Specify a hint over a relation. Hint should have a name and optional parameters.
930
+ message Hint {
931
+ // (Required) The input relation.
932
+ Relation input = 1;
933
+
934
+ // (Required) Hint name.
935
+ //
936
+ // Supported Join hints include BROADCAST, MERGE, SHUFFLE_HASH, SHUFFLE_REPLICATE_NL.
937
+ //
938
+ // Supported partitioning hints include COALESCE, REPARTITION, REPARTITION_BY_RANGE.
939
+ string name = 2;
940
+
941
+ // (Optional) Hint parameters.
942
+ repeated Expression parameters = 3;
943
+ }
944
+
945
+ // Unpivot a DataFrame from wide format to long format, optionally leaving identifier columns set.
946
+ message Unpivot {
947
+ // (Required) The input relation.
948
+ Relation input = 1;
949
+
950
+ // (Required) Id columns.
951
+ repeated Expression ids = 2;
952
+
953
+ // (Optional) Value columns to unpivot.
954
+ optional Values values = 3;
955
+
956
+ // (Required) Name of the variable column.
957
+ string variable_column_name = 4;
958
+
959
+ // (Required) Name of the value column.
960
+ string value_column_name = 5;
961
+
962
+ message Values {
963
+ repeated Expression values = 1;
964
+ }
965
+ }
966
+
967
+ // Transpose a DataFrame, switching rows to columns.
968
+ // Transforms the DataFrame such that the values in the specified index column
969
+ // become the new columns of the DataFrame.
970
+ message Transpose {
971
+ // (Required) The input relation.
972
+ Relation input = 1;
973
+
974
+ // (Optional) A list of columns that will be treated as the indices.
975
+ // Only single column is supported now.
976
+ repeated Expression index_columns = 2;
977
+ }
978
+
979
+ message UnresolvedTableValuedFunction {
980
+ // (Required) name (or unparsed name for user defined function) for the unresolved function.
981
+ string function_name = 1;
982
+
983
+ // (Optional) Function arguments. Empty arguments are allowed.
984
+ repeated Expression arguments = 2;
985
+ }
986
+
987
+ message ToSchema {
988
+ // (Required) The input relation.
989
+ Relation input = 1;
990
+
991
+ // (Required) The user provided schema.
992
+ //
993
+ // The Sever side will update the dataframe with this schema.
994
+ DataType schema = 2;
995
+ }
996
+
997
+ message RepartitionByExpression {
998
+ // (Required) The input relation.
999
+ Relation input = 1;
1000
+
1001
+ // (Required) The partitioning expressions.
1002
+ repeated Expression partition_exprs = 2;
1003
+
1004
+ // (Optional) number of partitions, must be positive.
1005
+ optional int32 num_partitions = 3;
1006
+ }
1007
+
1008
+ message MapPartitions {
1009
+ // (Required) Input relation for a mapPartitions-equivalent API: mapInPandas, mapInArrow.
1010
+ Relation input = 1;
1011
+
1012
+ // (Required) Input user-defined function.
1013
+ CommonInlineUserDefinedFunction func = 2;
1014
+
1015
+ // (Optional) Whether to use barrier mode execution or not.
1016
+ optional bool is_barrier = 3;
1017
+
1018
+ // (Optional) ResourceProfile id used for the stage level scheduling.
1019
+ optional int32 profile_id = 4;
1020
+ }
1021
+
1022
+ message GroupMap {
1023
+ // (Required) Input relation for Group Map API: apply, applyInPandas.
1024
+ Relation input = 1;
1025
+
1026
+ // (Required) Expressions for grouping keys.
1027
+ repeated Expression grouping_expressions = 2;
1028
+
1029
+ // (Required) Input user-defined function.
1030
+ CommonInlineUserDefinedFunction func = 3;
1031
+
1032
+ // (Optional) Expressions for sorting. Only used by Scala Sorted Group Map API.
1033
+ repeated Expression sorting_expressions = 4;
1034
+
1035
+ // Below fields are only used by (Flat)MapGroupsWithState
1036
+ // (Optional) Input relation for initial State.
1037
+ Relation initial_input = 5;
1038
+
1039
+ // (Optional) Expressions for grouping keys of the initial state input relation.
1040
+ repeated Expression initial_grouping_expressions = 6;
1041
+
1042
+ // (Optional) True if MapGroupsWithState, false if FlatMapGroupsWithState.
1043
+ optional bool is_map_groups_with_state = 7;
1044
+
1045
+ // (Optional) The output mode of the function.
1046
+ optional string output_mode = 8;
1047
+
1048
+ // (Optional) Timeout configuration for groups that do not receive data for a while.
1049
+ optional string timeout_conf = 9;
1050
+
1051
+ // (Optional) The schema for the grouped state.
1052
+ optional DataType state_schema = 10;
1053
+
1054
+ // Below fields are used by TransformWithState and TransformWithStateInPandas
1055
+ // (Optional) TransformWithState related parameters.
1056
+ optional TransformWithStateInfo transform_with_state_info = 11;
1057
+ }
1058
+
1059
+ // Additional input parameters used for TransformWithState operator.
1060
+ message TransformWithStateInfo {
1061
+ // (Required) Time mode string for transformWithState.
1062
+ string time_mode = 1;
1063
+
1064
+ // (Optional) Event time column name.
1065
+ optional string event_time_column_name = 2;
1066
+
1067
+ // (Optional) Schema for the output DataFrame.
1068
+ // Only required used for TransformWithStateInPandas.
1069
+ optional DataType output_schema = 3;
1070
+ }
1071
+
1072
+ message CoGroupMap {
1073
+ // (Required) One input relation for CoGroup Map API - applyInPandas.
1074
+ Relation input = 1;
1075
+
1076
+ // Expressions for grouping keys of the first input relation.
1077
+ repeated Expression input_grouping_expressions = 2;
1078
+
1079
+ // (Required) The other input relation.
1080
+ Relation other = 3;
1081
+
1082
+ // Expressions for grouping keys of the other input relation.
1083
+ repeated Expression other_grouping_expressions = 4;
1084
+
1085
+ // (Required) Input user-defined function.
1086
+ CommonInlineUserDefinedFunction func = 5;
1087
+
1088
+ // (Optional) Expressions for sorting. Only used by Scala Sorted CoGroup Map API.
1089
+ repeated Expression input_sorting_expressions = 6;
1090
+
1091
+ // (Optional) Expressions for sorting. Only used by Scala Sorted CoGroup Map API.
1092
+ repeated Expression other_sorting_expressions = 7;
1093
+ }
1094
+
1095
+ message ApplyInPandasWithState {
1096
+ // (Required) Input relation for applyInPandasWithState.
1097
+ Relation input = 1;
1098
+
1099
+ // (Required) Expressions for grouping keys.
1100
+ repeated Expression grouping_expressions = 2;
1101
+
1102
+ // (Required) Input user-defined function.
1103
+ CommonInlineUserDefinedFunction func = 3;
1104
+
1105
+ // (Required) Schema for the output DataFrame.
1106
+ string output_schema = 4;
1107
+
1108
+ // (Required) Schema for the state.
1109
+ string state_schema = 5;
1110
+
1111
+ // (Required) The output mode of the function.
1112
+ string output_mode = 6;
1113
+
1114
+ // (Required) Timeout configuration for groups that do not receive data for a while.
1115
+ string timeout_conf = 7;
1116
+ }
1117
+
1118
+ message CommonInlineUserDefinedTableFunction {
1119
+ // (Required) Name of the user-defined table function.
1120
+ string function_name = 1;
1121
+
1122
+ // (Optional) Whether the user-defined table function is deterministic.
1123
+ bool deterministic = 2;
1124
+
1125
+ // (Optional) Function input arguments. Empty arguments are allowed.
1126
+ repeated Expression arguments = 3;
1127
+
1128
+ // (Required) Type of the user-defined table function.
1129
+ oneof function {
1130
+ PythonUDTF python_udtf = 4;
1131
+ }
1132
+ }
1133
+
1134
+ message PythonUDTF {
1135
+ // (Optional) Return type of the Python UDTF.
1136
+ optional DataType return_type = 1;
1137
+
1138
+ // (Required) EvalType of the Python UDTF.
1139
+ int32 eval_type = 2;
1140
+
1141
+ // (Required) The encoded commands of the Python UDTF.
1142
+ bytes command = 3;
1143
+
1144
+ // (Required) Python version being used in the client.
1145
+ string python_ver = 4;
1146
+ }
1147
+
1148
+ message CommonInlineUserDefinedDataSource {
1149
+ // (Required) Name of the data source.
1150
+ string name = 1;
1151
+
1152
+ // (Required) The data source type.
1153
+ oneof data_source {
1154
+ PythonDataSource python_data_source = 2;
1155
+ }
1156
+ }
1157
+
1158
+ message PythonDataSource {
1159
+ // (Required) The encoded commands of the Python data source.
1160
+ bytes command = 1;
1161
+
1162
+ // (Required) Python version being used in the client.
1163
+ string python_ver = 2;
1164
+ }
1165
+
1166
+ // Collect arbitrary (named) metrics from a dataset.
1167
+ message CollectMetrics {
1168
+ // (Required) The input relation.
1169
+ Relation input = 1;
1170
+
1171
+ // (Required) Name of the metrics.
1172
+ string name = 2;
1173
+
1174
+ // (Required) The metric sequence.
1175
+ repeated Expression metrics = 3;
1176
+ }
1177
+
1178
+ message Parse {
1179
+ // (Required) Input relation to Parse. The input is expected to have single text column.
1180
+ Relation input = 1;
1181
+ // (Required) The expected format of the text.
1182
+ ParseFormat format = 2;
1183
+
1184
+ // (Optional) DataType representing the schema. If not set, Spark will infer the schema.
1185
+ optional DataType schema = 3;
1186
+
1187
+ // Options for the csv/json parser. The map key is case insensitive.
1188
+ map<string, string> options = 4;
1189
+ enum ParseFormat {
1190
+ PARSE_FORMAT_UNSPECIFIED = 0;
1191
+ PARSE_FORMAT_CSV = 1;
1192
+ PARSE_FORMAT_JSON = 2;
1193
+ }
1194
+ }
1195
+
1196
+ // Relation of type [[AsOfJoin]].
1197
+ //
1198
+ // `left` and `right` must be present.
1199
+ message AsOfJoin {
1200
+ // (Required) Left input relation for a Join.
1201
+ Relation left = 1;
1202
+
1203
+ // (Required) Right input relation for a Join.
1204
+ Relation right = 2;
1205
+
1206
+ // (Required) Field to join on in left DataFrame
1207
+ Expression left_as_of = 3;
1208
+
1209
+ // (Required) Field to join on in right DataFrame
1210
+ Expression right_as_of = 4;
1211
+
1212
+ // (Optional) The join condition. Could be unset when `using_columns` is utilized.
1213
+ //
1214
+ // This field does not co-exist with using_columns.
1215
+ Expression join_expr = 5;
1216
+
1217
+ // Optional. using_columns provides a list of columns that should present on both sides of
1218
+ // the join inputs that this Join will join on. For example A JOIN B USING col_name is
1219
+ // equivalent to A JOIN B on A.col_name = B.col_name.
1220
+ //
1221
+ // This field does not co-exist with join_condition.
1222
+ repeated string using_columns = 6;
1223
+
1224
+ // (Required) The join type.
1225
+ string join_type = 7;
1226
+
1227
+ // (Optional) The asof tolerance within this range.
1228
+ Expression tolerance = 8;
1229
+
1230
+ // (Required) Whether allow matching with the same value or not.
1231
+ bool allow_exact_matches = 9;
1232
+
1233
+ // (Required) Whether to search for prior, subsequent, or closest matches.
1234
+ string direction = 10;
1235
+ }
1236
+
1237
+ // Relation of type [[LateralJoin]].
1238
+ //
1239
+ // `left` and `right` must be present.
1240
+ message LateralJoin {
1241
+ // (Required) Left input relation for a Join.
1242
+ Relation left = 1;
1243
+
1244
+ // (Required) Right input relation for a Join.
1245
+ Relation right = 2;
1246
+
1247
+ // (Optional) The join condition.
1248
+ Expression join_condition = 3;
1249
+
1250
+ // (Required) The join type.
1251
+ Join.JoinType join_type = 4;
1252
+ }