1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
|
# Functions for structures
## TryMember {#trymember}
Trying to get a field from the structure. If it's not found among the fields or null in the structure value, use the default value.
Arguments:
1. Structure.
2. Field name.
3. Default value.
```yql
$struct = <|a:1|>;
SELECT
TryMember(
$struct,
"a",
123
) AS a, -- 1
TryMember(
$struct,
"b",
123
) AS b; -- 123
```
## ExpandStruct {#expandstruct}
Adding one or more new fields to the structure.
If the field set contains duplicate values, an error is returned.
Arguments:
* The first argument passes the source structure to be expanded.
* All the other arguments must be named, each argument adds a new field and the argument's name is used as the field's name (as in [AsStruct](basic.md#asstruct)).
#### Examples
```yql
$struct = <|a:1|>;
SELECT
ExpandStruct(
$struct,
2 AS b,
"3" AS c
) AS abc;
```
## AddMember {#addmember}
Adding one new field to the structure. If you need to add multiple fields, better use [ExpandStruct](#expandstruct).
If the field set contains duplicate values, an error is returned.
Arguments:
1. Source structure.
2. Name of the new field.
3. Value of the new field.
#### Examples
```yql
$struct = <|a:1|>;
SELECT
AddMember(
$struct,
"b",
2
) AS ab;
```
## RemoveMember {#removemember}
Removing a field from the structure.
If the entered field hasn't existed, an error is returned.
Arguments:
1. Source structure.
2. Field name.
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
RemoveMember(
$struct,
"b"
) AS a;
```
## ForceRemoveMember {#forceremovemember}
Removing a field from the structure.
If the entered field hasn't existed, unlike [RemoveMember](#removemember), the error is not returned.
Arguments:
1. Source structure.
2. Field name.
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
ForceRemoveMember(
$struct,
"c"
) AS ab;
```
## ChooseMembers {#choosemembers}
Selecting fields with specified names from the structure.
If any of the fields haven't existed, an error is returned.
Arguments:
1. Source structure.
2. List of field names.
#### Examples
```yql
$struct = <|a:1, b:2, c:3|>;
SELECT
ChooseMembers(
$struct,
["a", "b"]
) AS ab;
```
## RemoveMembers {#removemembers}
Excluding fields with specified names from the structure.
If any of the fields haven't existed, an error is returned.
Arguments:
1. Source structure.
2. List of field names.
#### Examples
```yql
$struct = <|a:1, b:2, c:3|>;
SELECT
RemoveMembers(
$struct,
["a", "b"]
) AS c;
```
## ForceRemoveMembers {#forceremovemembers}
Excluding fields with specified names from the structure.
If any of the fields haven't existed, it is ignored.
Arguments:
1. Source structure.
2. List of field names.
#### Examples
```yql
$struct = <|a:1, b:2, c:3|>;
SELECT
ForceRemoveMembers(
$struct,
["a", "b", "z"]
) AS c;
```
## CombineMembers {#combinemembers}
Combining the fields from multiple structures into a new structure.
If the resulting field set contains duplicate values, an error is returned.
Arguments: two or more structures.
#### Examples
```yql
$struct1 = <|a:1, b:2|>;
$struct2 = <|c:3|>;
SELECT
CombineMembers(
$struct1,
$struct2
) AS abc;
```
## FlattenMembers {#flattenmembers}
Combining the fields from multiple new structures into another new structure with prefix support.
If the resulting field set contains duplicate values, an error is returned.
Arguments: two or more tuples of two items: prefix and structure.
#### Examples
```yql
$struct1 = <|a:1, b:2|>;
$struct2 = <|c:3|>;
SELECT
FlattenMembers(
AsTuple("foo", $struct1), -- fooa, foob
AsTuple("bar", $struct2) -- barc
) AS abc;
```
## StructMembers {#structmembers}
Returns an unordered list of field names (possibly removing one Optional level) for a single argument that is a structure. For the `NULL` argument, an empty list of strings is returned.
Argument: structure
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
StructMembers($struct); -- ['a', 'b']
```
## RenameMembers {#renamemembers}
Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, an error is returned. For an Optional structure or `NULL`, the result has the same type.
Arguments:
1. Source structure.
2. A tuple of field names: the original name, the new name.
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
RenameMembers($struct, [('a', 'c'), ('a', 'e')]); -- (b:2, c:1, e:1)
```
## ForceRenameMembers {#forecerenamemembers}
Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, the name is ignored. For an Optional structure or `NULL`, the result has the same type.
Arguments:
1. Source structure.
2. A tuple of field names: the original name, the new name.
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
ForceRenameMembers($struct, [('a', 'c'), ('d', 'e')]); -- (b:2, c:1)
```
## GatherMembers {#gathermembers}
Returns an unordered list of tuples including the field name and value. For the `NULL` argument, `EmptyList` is returned. It can be used only in the cases when the types of items in the structure are the same or compatible. Returns an optional list for an optional structure.
Argument: structure
#### Examples
```yql
$struct = <|a:1, b:2|>;
SELECT
GatherMembers($struct); -- [('a', 1), ('b', 2)]
```
## SpreadMembers {#spreadmembers}
Creates a structure with a specified list of fields and applies a specified list of edits to it in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is Optional or `NULL`, the result has the same type. If the list of edits includes a field that is not in the list of expected fields, an error is returned.
Arguments:
1. List of tuples: field name, field value.
2. A list of all possible field names in the structure.
#### Examples
```yql
SELECT
SpreadMembers([('a',1),('a',2)],['a','b']); -- (a: 2, b: null)
```
## ForceSpreadMembers {#forcespreadmembers}
Creates a structure with a specified list of fields and applies to it the specified list of updates in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is optional or equal to `NULL`, the result has the same type. If the list of updates includes a field that is not in the list of expected fields, this edit is ignored.
Arguments:
1. List of tuples: field name, field value.
2. A list of all possible field names in the structure.
#### Examples
```yql
SELECT
ForceSpreadMembers([('a',1),('a',2),('c',100)],['a','b']); -- (a: 2, b: null)
```
## StructUnion, StructIntersection, StructDifference, StructSymmetricDifference
Combine two structures using one of the four methods (using the provided lambda to merge fields with the same name):
* `StructUnion` adds all fields of both of the structures to the result.
* `StructIntersection` adds only the fields which are present in both of the structures.
* `StructDifference` adds only the fields of `left`, which are absent in `right`.
* `StructSymmetricDifference` adds all fields that are present in exactly one of the structures.
#### Signatures
```yql
StructUnion(left:Struct<...>, right:Struct<...>[, mergeLambda:(name:String, l:T1?, r:T2?)->T])->Struct<...>
StructIntersection(left:Struct<...>, right:Struct<...>[, mergeLambda:(name:String, l:T1?, r:T2?)->T])->Struct<...>
StructDifference(left:Struct<...>, right:Struct<...>)->Struct<...>
StructSymmetricDifference(left:Struct<...>, right:Struct<...>)->Struct<...>
```
Arguments:
1. `left` - first structure.
2. `right` - second structure.
3. `mergeLambda` - _(optional)_ function to merge fields with the same name (arguments: field name, `Optional` field value of the first struct, `Optional` field value of the second struct - arguments are `Nothing<T?>` in case of absence of the corresponding struct field). By default, if present, the first structure's field value is used; otherwise, the second one's value is used.
#### Examples
```yql
$merge = ($name, $l, $r) -> {
return ($l ?? 0) + ($r ?? 0);
};
$left = <|a: 1, b: 2, c: 3|>;
$right = <|c: 1, d: 2, e: 3|>;
SELECT
StructUnion($left, $right), -- <|a: 1, b: 2, c: 3, d: 2, e: 3|>
StructUnion($left, $right, $merge), -- <|a: 1, b: 2, c: 4, d: 2, e: 3|>
StructIntersection($left, $right, $merge), -- <|c: 4|>
StructDifference($left, $right), -- <|a: 1, b: 1|>
StructSymmetricDifference($left, $right) -- <|a: 1, b: 2, d: 2, e: 3|>
;
```
|