1use crate::transaction::{Operation, UpdateMap};
16use std::collections::HashSet;
17
18impl PartialEq for Operation {
19 fn eq(&self, other: &Self) -> bool {
20 fn compare_vec<T: PartialEq>(a: &[T], b: &[T]) -> bool {
26 a.len() == b.len() && a.iter().all(|f| b.contains(f))
27 }
28 match (self, other) {
29 (Self::Append { fragments: a }, Self::Append { fragments: b }) => compare_vec(a, b),
30 (
31 Self::Clone {
32 is_shallow: a_is_shallow,
33 ref_name: a_ref_name,
34 ref_version: a_ref_version,
35 ref_path: a_source_path,
36 branch_name: a_branch_name,
37 },
38 Self::Clone {
39 is_shallow: b_is_shallow,
40 ref_name: b_ref_name,
41 ref_version: b_ref_version,
42 ref_path: b_source_path,
43 branch_name: b_branch_name,
44 },
45 ) => {
46 a_is_shallow == b_is_shallow
47 && a_ref_name == b_ref_name
48 && a_ref_version == b_ref_version
49 && a_source_path == b_source_path
50 && a_branch_name == b_branch_name
51 }
52 (
53 Self::Delete {
54 updated_fragments: a_updated,
55 deleted_fragment_ids: a_deleted,
56 predicate: a_predicate,
57 },
58 Self::Delete {
59 updated_fragments: b_updated,
60 deleted_fragment_ids: b_deleted,
61 predicate: b_predicate,
62 },
63 ) => {
64 compare_vec(a_updated, b_updated)
65 && compare_vec(a_deleted, b_deleted)
66 && a_predicate == b_predicate
67 }
68 (
69 Self::Overwrite {
70 fragments: a_fragments,
71 schema: a_schema,
72 config_upsert_values: a_config,
73 initial_bases: a_initial,
74 },
75 Self::Overwrite {
76 fragments: b_fragments,
77 schema: b_schema,
78 config_upsert_values: b_config,
79 initial_bases: b_initial,
80 },
81 ) => {
82 compare_vec(a_fragments, b_fragments)
83 && a_schema == b_schema
84 && a_config == b_config
85 && a_initial == b_initial
86 }
87 (
88 Self::CreateIndex {
89 new_indices: a_new,
90 removed_indices: a_removed,
91 },
92 Self::CreateIndex {
93 new_indices: b_new,
94 removed_indices: b_removed,
95 },
96 ) => compare_vec(a_new, b_new) && compare_vec(a_removed, b_removed),
97 (
98 Self::Rewrite {
99 groups: a_groups,
100 rewritten_indices: a_indices,
101 frag_reuse_index: a_frag_reuse_index,
102 },
103 Self::Rewrite {
104 groups: b_groups,
105 rewritten_indices: b_indices,
106 frag_reuse_index: b_frag_reuse_index,
107 },
108 ) => {
109 compare_vec(a_groups, b_groups)
110 && compare_vec(a_indices, b_indices)
111 && a_frag_reuse_index == b_frag_reuse_index
112 }
113 (
114 Self::Merge {
115 fragments: a_fragments,
116 schema: a_schema,
117 preserves_nullability: a_preserves,
118 },
119 Self::Merge {
120 fragments: b_fragments,
121 schema: b_schema,
122 preserves_nullability: b_preserves,
123 },
124 ) => {
125 compare_vec(a_fragments, b_fragments)
126 && a_schema == b_schema
127 && a_preserves == b_preserves
128 }
129 (Self::Restore { version: a }, Self::Restore { version: b }) => a == b,
130 (
131 Self::ReserveFragments { num_fragments: a },
132 Self::ReserveFragments { num_fragments: b },
133 ) => a == b,
134 (
135 Self::Update {
136 removed_fragment_ids: a_removed,
137 updated_fragments: a_updated,
138 new_fragments: a_new,
139 fields_modified: a_fields,
140 compacted_sstables: a_compacted_sstables,
141 fields_for_preserving_frag_bitmap: a_fields_for_preserving_frag_bitmap,
142 update_mode: a_update_mode,
143 inserted_rows_filter: a_inserted_rows_filter,
144 updated_fragment_offsets: a_updated_fragment_offsets,
145 },
146 Self::Update {
147 removed_fragment_ids: b_removed,
148 updated_fragments: b_updated,
149 new_fragments: b_new,
150 fields_modified: b_fields,
151 compacted_sstables: b_compacted_sstables,
152 fields_for_preserving_frag_bitmap: b_fields_for_preserving_frag_bitmap,
153 update_mode: b_update_mode,
154 inserted_rows_filter: b_inserted_rows_filter,
155 updated_fragment_offsets: b_updated_fragment_offsets,
156 },
157 ) => {
158 compare_vec(a_removed, b_removed)
159 && compare_vec(a_updated, b_updated)
160 && compare_vec(a_new, b_new)
161 && compare_vec(a_fields, b_fields)
162 && compare_vec(a_compacted_sstables, b_compacted_sstables)
163 && compare_vec(
164 a_fields_for_preserving_frag_bitmap,
165 b_fields_for_preserving_frag_bitmap,
166 )
167 && a_update_mode == b_update_mode
168 && a_inserted_rows_filter == b_inserted_rows_filter
169 && a_updated_fragment_offsets == b_updated_fragment_offsets
170 }
171 (
172 Self::Project {
173 schema: a,
174 preserves_nullability: a_preserves,
175 },
176 Self::Project {
177 schema: b,
178 preserves_nullability: b_preserves,
179 },
180 ) => a == b && a_preserves == b_preserves,
181 (
182 Self::UpdateConfig {
183 config_updates: a_config,
184 table_metadata_updates: a_table_metadata,
185 schema_metadata_updates: a_schema,
186 field_metadata_updates: a_field,
187 },
188 Self::UpdateConfig {
189 config_updates: b_config,
190 table_metadata_updates: b_table_metadata,
191 schema_metadata_updates: b_schema,
192 field_metadata_updates: b_field,
193 },
194 ) => {
195 a_config == b_config
196 && a_table_metadata == b_table_metadata
197 && a_schema == b_schema
198 && a_field == b_field
199 }
200 (
201 Self::DataReplacement { replacements: a },
202 Self::DataReplacement { replacements: b },
203 ) => a.len() == b.len() && a.iter().all(|r| b.contains(r)),
204 (Self::Append { .. }, Self::Delete { .. }) => {
208 std::mem::discriminant(self) == std::mem::discriminant(other)
209 }
210 (Self::Append { .. }, Self::Overwrite { .. }) => {
211 std::mem::discriminant(self) == std::mem::discriminant(other)
212 }
213 (Self::Append { .. }, Self::CreateIndex { .. }) => {
214 std::mem::discriminant(self) == std::mem::discriminant(other)
215 }
216 (Self::Append { .. }, Self::Rewrite { .. }) => {
217 std::mem::discriminant(self) == std::mem::discriminant(other)
218 }
219 (Self::Append { .. }, Self::Merge { .. }) => {
220 std::mem::discriminant(self) == std::mem::discriminant(other)
221 }
222 (Self::Append { .. }, Self::Restore { .. }) => {
223 std::mem::discriminant(self) == std::mem::discriminant(other)
224 }
225 (Self::Append { .. }, Self::ReserveFragments { .. }) => {
226 std::mem::discriminant(self) == std::mem::discriminant(other)
227 }
228 (Self::Append { .. }, Self::Update { .. }) => {
229 std::mem::discriminant(self) == std::mem::discriminant(other)
230 }
231 (Self::Append { .. }, Self::Project { .. }) => {
232 std::mem::discriminant(self) == std::mem::discriminant(other)
233 }
234 (Self::Append { .. }, Self::UpdateConfig { .. }) => {
235 std::mem::discriminant(self) == std::mem::discriminant(other)
236 }
237 (Self::Append { .. }, Self::DataReplacement { .. }) => {
238 std::mem::discriminant(self) == std::mem::discriminant(other)
239 }
240 (Self::Append { .. }, Self::UpdateMemWalState { .. }) => {
241 std::mem::discriminant(self) == std::mem::discriminant(other)
242 }
243 (Self::Append { .. }, Self::Clone { .. }) => {
244 std::mem::discriminant(self) == std::mem::discriminant(other)
245 }
246
247 (Self::Delete { .. }, Self::Append { .. }) => {
248 std::mem::discriminant(self) == std::mem::discriminant(other)
249 }
250 (Self::Delete { .. }, Self::Overwrite { .. }) => {
251 std::mem::discriminant(self) == std::mem::discriminant(other)
252 }
253 (Self::Delete { .. }, Self::CreateIndex { .. }) => {
254 std::mem::discriminant(self) == std::mem::discriminant(other)
255 }
256 (Self::Delete { .. }, Self::Rewrite { .. }) => {
257 std::mem::discriminant(self) == std::mem::discriminant(other)
258 }
259 (Self::Delete { .. }, Self::Merge { .. }) => {
260 std::mem::discriminant(self) == std::mem::discriminant(other)
261 }
262 (Self::Delete { .. }, Self::Restore { .. }) => {
263 std::mem::discriminant(self) == std::mem::discriminant(other)
264 }
265 (Self::Delete { .. }, Self::ReserveFragments { .. }) => {
266 std::mem::discriminant(self) == std::mem::discriminant(other)
267 }
268 (Self::Delete { .. }, Self::Update { .. }) => {
269 std::mem::discriminant(self) == std::mem::discriminant(other)
270 }
271 (Self::Delete { .. }, Self::Project { .. }) => {
272 std::mem::discriminant(self) == std::mem::discriminant(other)
273 }
274 (Self::Delete { .. }, Self::UpdateConfig { .. }) => {
275 std::mem::discriminant(self) == std::mem::discriminant(other)
276 }
277 (Self::Delete { .. }, Self::DataReplacement { .. }) => {
278 std::mem::discriminant(self) == std::mem::discriminant(other)
279 }
280 (Self::Delete { .. }, Self::UpdateMemWalState { .. }) => {
281 std::mem::discriminant(self) == std::mem::discriminant(other)
282 }
283 (Self::Delete { .. }, Self::Clone { .. }) => {
284 std::mem::discriminant(self) == std::mem::discriminant(other)
285 }
286
287 (Self::Overwrite { .. }, Self::Append { .. }) => {
288 std::mem::discriminant(self) == std::mem::discriminant(other)
289 }
290 (Self::Overwrite { .. }, Self::Delete { .. }) => {
291 std::mem::discriminant(self) == std::mem::discriminant(other)
292 }
293 (Self::Overwrite { .. }, Self::CreateIndex { .. }) => {
294 std::mem::discriminant(self) == std::mem::discriminant(other)
295 }
296 (Self::Overwrite { .. }, Self::Rewrite { .. }) => {
297 std::mem::discriminant(self) == std::mem::discriminant(other)
298 }
299 (Self::Overwrite { .. }, Self::Merge { .. }) => {
300 std::mem::discriminant(self) == std::mem::discriminant(other)
301 }
302 (Self::Overwrite { .. }, Self::Restore { .. }) => {
303 std::mem::discriminant(self) == std::mem::discriminant(other)
304 }
305 (Self::Overwrite { .. }, Self::ReserveFragments { .. }) => {
306 std::mem::discriminant(self) == std::mem::discriminant(other)
307 }
308 (Self::Overwrite { .. }, Self::Update { .. }) => {
309 std::mem::discriminant(self) == std::mem::discriminant(other)
310 }
311 (Self::Overwrite { .. }, Self::Project { .. }) => {
312 std::mem::discriminant(self) == std::mem::discriminant(other)
313 }
314 (Self::Overwrite { .. }, Self::UpdateConfig { .. }) => {
315 std::mem::discriminant(self) == std::mem::discriminant(other)
316 }
317 (Self::Overwrite { .. }, Self::DataReplacement { .. }) => {
318 std::mem::discriminant(self) == std::mem::discriminant(other)
319 }
320 (Self::Overwrite { .. }, Self::UpdateMemWalState { .. }) => {
321 std::mem::discriminant(self) == std::mem::discriminant(other)
322 }
323 (Self::Overwrite { .. }, Self::Clone { .. }) => {
324 std::mem::discriminant(self) == std::mem::discriminant(other)
325 }
326
327 (Self::CreateIndex { .. }, Self::Append { .. }) => {
328 std::mem::discriminant(self) == std::mem::discriminant(other)
329 }
330 (Self::CreateIndex { .. }, Self::Delete { .. }) => {
331 std::mem::discriminant(self) == std::mem::discriminant(other)
332 }
333 (Self::CreateIndex { .. }, Self::Overwrite { .. }) => {
334 std::mem::discriminant(self) == std::mem::discriminant(other)
335 }
336 (Self::CreateIndex { .. }, Self::Rewrite { .. }) => {
337 std::mem::discriminant(self) == std::mem::discriminant(other)
338 }
339 (Self::CreateIndex { .. }, Self::Merge { .. }) => {
340 std::mem::discriminant(self) == std::mem::discriminant(other)
341 }
342 (Self::CreateIndex { .. }, Self::Restore { .. }) => {
343 std::mem::discriminant(self) == std::mem::discriminant(other)
344 }
345 (Self::CreateIndex { .. }, Self::ReserveFragments { .. }) => {
346 std::mem::discriminant(self) == std::mem::discriminant(other)
347 }
348 (Self::CreateIndex { .. }, Self::Update { .. }) => {
349 std::mem::discriminant(self) == std::mem::discriminant(other)
350 }
351 (Self::CreateIndex { .. }, Self::Project { .. }) => {
352 std::mem::discriminant(self) == std::mem::discriminant(other)
353 }
354 (Self::CreateIndex { .. }, Self::UpdateConfig { .. }) => {
355 std::mem::discriminant(self) == std::mem::discriminant(other)
356 }
357 (Self::CreateIndex { .. }, Self::DataReplacement { .. }) => {
358 std::mem::discriminant(self) == std::mem::discriminant(other)
359 }
360 (Self::CreateIndex { .. }, Self::UpdateMemWalState { .. }) => {
361 std::mem::discriminant(self) == std::mem::discriminant(other)
362 }
363 (Self::CreateIndex { .. }, Self::Clone { .. }) => {
364 std::mem::discriminant(self) == std::mem::discriminant(other)
365 }
366
367 (Self::Rewrite { .. }, Self::Append { .. }) => {
368 std::mem::discriminant(self) == std::mem::discriminant(other)
369 }
370 (Self::Rewrite { .. }, Self::Delete { .. }) => {
371 std::mem::discriminant(self) == std::mem::discriminant(other)
372 }
373 (Self::Rewrite { .. }, Self::Overwrite { .. }) => {
374 std::mem::discriminant(self) == std::mem::discriminant(other)
375 }
376 (Self::Rewrite { .. }, Self::CreateIndex { .. }) => {
377 std::mem::discriminant(self) == std::mem::discriminant(other)
378 }
379 (Self::Rewrite { .. }, Self::Merge { .. }) => {
380 std::mem::discriminant(self) == std::mem::discriminant(other)
381 }
382 (Self::Rewrite { .. }, Self::Restore { .. }) => {
383 std::mem::discriminant(self) == std::mem::discriminant(other)
384 }
385 (Self::Rewrite { .. }, Self::ReserveFragments { .. }) => {
386 std::mem::discriminant(self) == std::mem::discriminant(other)
387 }
388 (Self::Rewrite { .. }, Self::Update { .. }) => {
389 std::mem::discriminant(self) == std::mem::discriminant(other)
390 }
391 (Self::Rewrite { .. }, Self::Project { .. }) => {
392 std::mem::discriminant(self) == std::mem::discriminant(other)
393 }
394 (Self::Rewrite { .. }, Self::UpdateConfig { .. }) => {
395 std::mem::discriminant(self) == std::mem::discriminant(other)
396 }
397 (Self::Rewrite { .. }, Self::DataReplacement { .. }) => {
398 std::mem::discriminant(self) == std::mem::discriminant(other)
399 }
400 (Self::Rewrite { .. }, Self::UpdateMemWalState { .. }) => {
401 std::mem::discriminant(self) == std::mem::discriminant(other)
402 }
403 (Self::Rewrite { .. }, Self::Clone { .. }) => {
404 std::mem::discriminant(self) == std::mem::discriminant(other)
405 }
406
407 (Self::Merge { .. }, Self::Append { .. }) => {
408 std::mem::discriminant(self) == std::mem::discriminant(other)
409 }
410 (Self::Merge { .. }, Self::Delete { .. }) => {
411 std::mem::discriminant(self) == std::mem::discriminant(other)
412 }
413 (Self::Merge { .. }, Self::Overwrite { .. }) => {
414 std::mem::discriminant(self) == std::mem::discriminant(other)
415 }
416 (Self::Merge { .. }, Self::CreateIndex { .. }) => {
417 std::mem::discriminant(self) == std::mem::discriminant(other)
418 }
419 (Self::Merge { .. }, Self::Rewrite { .. }) => {
420 std::mem::discriminant(self) == std::mem::discriminant(other)
421 }
422 (Self::Merge { .. }, Self::Restore { .. }) => {
423 std::mem::discriminant(self) == std::mem::discriminant(other)
424 }
425 (Self::Merge { .. }, Self::ReserveFragments { .. }) => {
426 std::mem::discriminant(self) == std::mem::discriminant(other)
427 }
428 (Self::Merge { .. }, Self::Update { .. }) => {
429 std::mem::discriminant(self) == std::mem::discriminant(other)
430 }
431 (Self::Merge { .. }, Self::Project { .. }) => {
432 std::mem::discriminant(self) == std::mem::discriminant(other)
433 }
434 (Self::Merge { .. }, Self::UpdateConfig { .. }) => {
435 std::mem::discriminant(self) == std::mem::discriminant(other)
436 }
437 (Self::Merge { .. }, Self::DataReplacement { .. }) => {
438 std::mem::discriminant(self) == std::mem::discriminant(other)
439 }
440 (Self::Merge { .. }, Self::UpdateMemWalState { .. }) => {
441 std::mem::discriminant(self) == std::mem::discriminant(other)
442 }
443 (Self::Merge { .. }, Self::Clone { .. }) => {
444 std::mem::discriminant(self) == std::mem::discriminant(other)
445 }
446
447 (Self::Restore { .. }, Self::Append { .. }) => {
448 std::mem::discriminant(self) == std::mem::discriminant(other)
449 }
450 (Self::Restore { .. }, Self::Delete { .. }) => {
451 std::mem::discriminant(self) == std::mem::discriminant(other)
452 }
453 (Self::Restore { .. }, Self::Overwrite { .. }) => {
454 std::mem::discriminant(self) == std::mem::discriminant(other)
455 }
456 (Self::Restore { .. }, Self::CreateIndex { .. }) => {
457 std::mem::discriminant(self) == std::mem::discriminant(other)
458 }
459 (Self::Restore { .. }, Self::Rewrite { .. }) => {
460 std::mem::discriminant(self) == std::mem::discriminant(other)
461 }
462 (Self::Restore { .. }, Self::Merge { .. }) => {
463 std::mem::discriminant(self) == std::mem::discriminant(other)
464 }
465 (Self::Restore { .. }, Self::ReserveFragments { .. }) => {
466 std::mem::discriminant(self) == std::mem::discriminant(other)
467 }
468 (Self::Restore { .. }, Self::Update { .. }) => {
469 std::mem::discriminant(self) == std::mem::discriminant(other)
470 }
471 (Self::Restore { .. }, Self::Project { .. }) => {
472 std::mem::discriminant(self) == std::mem::discriminant(other)
473 }
474 (Self::Restore { .. }, Self::UpdateConfig { .. }) => {
475 std::mem::discriminant(self) == std::mem::discriminant(other)
476 }
477 (Self::Restore { .. }, Self::DataReplacement { .. }) => {
478 std::mem::discriminant(self) == std::mem::discriminant(other)
479 }
480 (Self::Restore { .. }, Self::UpdateMemWalState { .. }) => {
481 std::mem::discriminant(self) == std::mem::discriminant(other)
482 }
483 (Self::Restore { .. }, Self::Clone { .. }) => {
484 std::mem::discriminant(self) == std::mem::discriminant(other)
485 }
486
487 (Self::ReserveFragments { .. }, Self::Append { .. }) => {
488 std::mem::discriminant(self) == std::mem::discriminant(other)
489 }
490 (Self::ReserveFragments { .. }, Self::Delete { .. }) => {
491 std::mem::discriminant(self) == std::mem::discriminant(other)
492 }
493 (Self::ReserveFragments { .. }, Self::Overwrite { .. }) => {
494 std::mem::discriminant(self) == std::mem::discriminant(other)
495 }
496 (Self::ReserveFragments { .. }, Self::CreateIndex { .. }) => {
497 std::mem::discriminant(self) == std::mem::discriminant(other)
498 }
499 (Self::ReserveFragments { .. }, Self::Rewrite { .. }) => {
500 std::mem::discriminant(self) == std::mem::discriminant(other)
501 }
502 (Self::ReserveFragments { .. }, Self::Merge { .. }) => {
503 std::mem::discriminant(self) == std::mem::discriminant(other)
504 }
505 (Self::ReserveFragments { .. }, Self::Restore { .. }) => {
506 std::mem::discriminant(self) == std::mem::discriminant(other)
507 }
508 (Self::ReserveFragments { .. }, Self::Update { .. }) => {
509 std::mem::discriminant(self) == std::mem::discriminant(other)
510 }
511 (Self::ReserveFragments { .. }, Self::Project { .. }) => {
512 std::mem::discriminant(self) == std::mem::discriminant(other)
513 }
514 (Self::ReserveFragments { .. }, Self::UpdateConfig { .. }) => {
515 std::mem::discriminant(self) == std::mem::discriminant(other)
516 }
517 (Self::ReserveFragments { .. }, Self::DataReplacement { .. }) => {
518 std::mem::discriminant(self) == std::mem::discriminant(other)
519 }
520 (Self::ReserveFragments { .. }, Self::UpdateMemWalState { .. }) => {
521 std::mem::discriminant(self) == std::mem::discriminant(other)
522 }
523 (Self::ReserveFragments { .. }, Self::Clone { .. }) => {
524 std::mem::discriminant(self) == std::mem::discriminant(other)
525 }
526
527 (Self::Update { .. }, Self::Append { .. }) => {
528 std::mem::discriminant(self) == std::mem::discriminant(other)
529 }
530 (Self::Update { .. }, Self::Delete { .. }) => {
531 std::mem::discriminant(self) == std::mem::discriminant(other)
532 }
533 (Self::Update { .. }, Self::Overwrite { .. }) => {
534 std::mem::discriminant(self) == std::mem::discriminant(other)
535 }
536 (Self::Update { .. }, Self::CreateIndex { .. }) => {
537 std::mem::discriminant(self) == std::mem::discriminant(other)
538 }
539 (Self::Update { .. }, Self::Rewrite { .. }) => {
540 std::mem::discriminant(self) == std::mem::discriminant(other)
541 }
542 (Self::Update { .. }, Self::Merge { .. }) => {
543 std::mem::discriminant(self) == std::mem::discriminant(other)
544 }
545 (Self::Update { .. }, Self::Restore { .. }) => {
546 std::mem::discriminant(self) == std::mem::discriminant(other)
547 }
548 (Self::Update { .. }, Self::ReserveFragments { .. }) => {
549 std::mem::discriminant(self) == std::mem::discriminant(other)
550 }
551 (Self::Update { .. }, Self::Project { .. }) => {
552 std::mem::discriminant(self) == std::mem::discriminant(other)
553 }
554 (Self::Update { .. }, Self::UpdateConfig { .. }) => {
555 std::mem::discriminant(self) == std::mem::discriminant(other)
556 }
557 (Self::Update { .. }, Self::DataReplacement { .. }) => {
558 std::mem::discriminant(self) == std::mem::discriminant(other)
559 }
560 (Self::Update { .. }, Self::UpdateMemWalState { .. }) => {
561 std::mem::discriminant(self) == std::mem::discriminant(other)
562 }
563 (Self::Update { .. }, Self::Clone { .. }) => {
564 std::mem::discriminant(self) == std::mem::discriminant(other)
565 }
566
567 (Self::Project { .. }, Self::Append { .. }) => {
568 std::mem::discriminant(self) == std::mem::discriminant(other)
569 }
570 (Self::Project { .. }, Self::Delete { .. }) => {
571 std::mem::discriminant(self) == std::mem::discriminant(other)
572 }
573 (Self::Project { .. }, Self::Overwrite { .. }) => {
574 std::mem::discriminant(self) == std::mem::discriminant(other)
575 }
576 (Self::Project { .. }, Self::CreateIndex { .. }) => {
577 std::mem::discriminant(self) == std::mem::discriminant(other)
578 }
579 (Self::Project { .. }, Self::Rewrite { .. }) => {
580 std::mem::discriminant(self) == std::mem::discriminant(other)
581 }
582 (Self::Project { .. }, Self::Merge { .. }) => {
583 std::mem::discriminant(self) == std::mem::discriminant(other)
584 }
585 (Self::Project { .. }, Self::Restore { .. }) => {
586 std::mem::discriminant(self) == std::mem::discriminant(other)
587 }
588 (Self::Project { .. }, Self::ReserveFragments { .. }) => {
589 std::mem::discriminant(self) == std::mem::discriminant(other)
590 }
591 (Self::Project { .. }, Self::Update { .. }) => {
592 std::mem::discriminant(self) == std::mem::discriminant(other)
593 }
594 (Self::Project { .. }, Self::UpdateConfig { .. }) => {
595 std::mem::discriminant(self) == std::mem::discriminant(other)
596 }
597 (Self::Project { .. }, Self::DataReplacement { .. }) => {
598 std::mem::discriminant(self) == std::mem::discriminant(other)
599 }
600 (Self::Project { .. }, Self::UpdateMemWalState { .. }) => {
601 std::mem::discriminant(self) == std::mem::discriminant(other)
602 }
603 (Self::Project { .. }, Self::Clone { .. }) => {
604 std::mem::discriminant(self) == std::mem::discriminant(other)
605 }
606
607 (Self::UpdateConfig { .. }, Self::Append { .. }) => {
608 std::mem::discriminant(self) == std::mem::discriminant(other)
609 }
610 (Self::UpdateConfig { .. }, Self::Delete { .. }) => {
611 std::mem::discriminant(self) == std::mem::discriminant(other)
612 }
613 (Self::UpdateConfig { .. }, Self::Overwrite { .. }) => {
614 std::mem::discriminant(self) == std::mem::discriminant(other)
615 }
616 (Self::UpdateConfig { .. }, Self::CreateIndex { .. }) => {
617 std::mem::discriminant(self) == std::mem::discriminant(other)
618 }
619 (Self::UpdateConfig { .. }, Self::Rewrite { .. }) => {
620 std::mem::discriminant(self) == std::mem::discriminant(other)
621 }
622 (Self::UpdateConfig { .. }, Self::Merge { .. }) => {
623 std::mem::discriminant(self) == std::mem::discriminant(other)
624 }
625 (Self::UpdateConfig { .. }, Self::Restore { .. }) => {
626 std::mem::discriminant(self) == std::mem::discriminant(other)
627 }
628 (Self::UpdateConfig { .. }, Self::ReserveFragments { .. }) => {
629 std::mem::discriminant(self) == std::mem::discriminant(other)
630 }
631 (Self::UpdateConfig { .. }, Self::Update { .. }) => {
632 std::mem::discriminant(self) == std::mem::discriminant(other)
633 }
634 (Self::UpdateConfig { .. }, Self::Project { .. }) => {
635 std::mem::discriminant(self) == std::mem::discriminant(other)
636 }
637 (Self::UpdateConfig { .. }, Self::DataReplacement { .. }) => {
638 std::mem::discriminant(self) == std::mem::discriminant(other)
639 }
640 (Self::UpdateConfig { .. }, Self::UpdateMemWalState { .. }) => {
641 std::mem::discriminant(self) == std::mem::discriminant(other)
642 }
643 (Self::UpdateConfig { .. }, Self::Clone { .. }) => {
644 std::mem::discriminant(self) == std::mem::discriminant(other)
645 }
646
647 (Self::DataReplacement { .. }, Self::Append { .. }) => {
648 std::mem::discriminant(self) == std::mem::discriminant(other)
649 }
650 (Self::DataReplacement { .. }, Self::Delete { .. }) => {
651 std::mem::discriminant(self) == std::mem::discriminant(other)
652 }
653 (Self::DataReplacement { .. }, Self::Overwrite { .. }) => {
654 std::mem::discriminant(self) == std::mem::discriminant(other)
655 }
656 (Self::DataReplacement { .. }, Self::CreateIndex { .. }) => {
657 std::mem::discriminant(self) == std::mem::discriminant(other)
658 }
659 (Self::DataReplacement { .. }, Self::Rewrite { .. }) => {
660 std::mem::discriminant(self) == std::mem::discriminant(other)
661 }
662 (Self::DataReplacement { .. }, Self::Merge { .. }) => {
663 std::mem::discriminant(self) == std::mem::discriminant(other)
664 }
665 (Self::DataReplacement { .. }, Self::Restore { .. }) => {
666 std::mem::discriminant(self) == std::mem::discriminant(other)
667 }
668 (Self::DataReplacement { .. }, Self::ReserveFragments { .. }) => {
669 std::mem::discriminant(self) == std::mem::discriminant(other)
670 }
671 (Self::DataReplacement { .. }, Self::Update { .. }) => {
672 std::mem::discriminant(self) == std::mem::discriminant(other)
673 }
674 (Self::DataReplacement { .. }, Self::Project { .. }) => {
675 std::mem::discriminant(self) == std::mem::discriminant(other)
676 }
677 (Self::DataReplacement { .. }, Self::UpdateConfig { .. }) => {
678 std::mem::discriminant(self) == std::mem::discriminant(other)
679 }
680 (Self::DataReplacement { .. }, Self::UpdateMemWalState { .. }) => {
681 std::mem::discriminant(self) == std::mem::discriminant(other)
682 }
683 (Self::DataReplacement { .. }, Self::Clone { .. }) => {
684 std::mem::discriminant(self) == std::mem::discriminant(other)
685 }
686
687 (Self::UpdateMemWalState { .. }, Self::Append { .. }) => {
688 std::mem::discriminant(self) == std::mem::discriminant(other)
689 }
690 (Self::UpdateMemWalState { .. }, Self::Delete { .. }) => {
691 std::mem::discriminant(self) == std::mem::discriminant(other)
692 }
693 (Self::UpdateMemWalState { .. }, Self::Overwrite { .. }) => {
694 std::mem::discriminant(self) == std::mem::discriminant(other)
695 }
696 (Self::UpdateMemWalState { .. }, Self::CreateIndex { .. }) => {
697 std::mem::discriminant(self) == std::mem::discriminant(other)
698 }
699 (Self::UpdateMemWalState { .. }, Self::Rewrite { .. }) => {
700 std::mem::discriminant(self) == std::mem::discriminant(other)
701 }
702 (Self::UpdateMemWalState { .. }, Self::Merge { .. }) => {
703 std::mem::discriminant(self) == std::mem::discriminant(other)
704 }
705 (Self::UpdateMemWalState { .. }, Self::Restore { .. }) => {
706 std::mem::discriminant(self) == std::mem::discriminant(other)
707 }
708 (Self::UpdateMemWalState { .. }, Self::ReserveFragments { .. }) => {
709 std::mem::discriminant(self) == std::mem::discriminant(other)
710 }
711 (Self::UpdateMemWalState { .. }, Self::Update { .. }) => {
712 std::mem::discriminant(self) == std::mem::discriminant(other)
713 }
714 (Self::UpdateMemWalState { .. }, Self::Project { .. }) => {
715 std::mem::discriminant(self) == std::mem::discriminant(other)
716 }
717 (Self::UpdateMemWalState { .. }, Self::UpdateConfig { .. }) => {
718 std::mem::discriminant(self) == std::mem::discriminant(other)
719 }
720 (Self::UpdateMemWalState { .. }, Self::DataReplacement { .. }) => {
721 std::mem::discriminant(self) == std::mem::discriminant(other)
722 }
723 (Self::UpdateMemWalState { .. }, Self::Clone { .. }) => {
724 std::mem::discriminant(self) == std::mem::discriminant(other)
725 }
726 (
727 Self::UpdateMemWalState {
728 compacted_sstables: a_compacted,
729 },
730 Self::UpdateMemWalState {
731 compacted_sstables: b_compacted,
732 },
733 ) => compare_vec(a_compacted, b_compacted),
734 (Self::Clone { .. }, Self::Append { .. }) => {
735 std::mem::discriminant(self) == std::mem::discriminant(other)
736 }
737 (Self::Clone { .. }, Self::Delete { .. }) => {
738 std::mem::discriminant(self) == std::mem::discriminant(other)
739 }
740 (Self::Clone { .. }, Self::Overwrite { .. }) => {
741 std::mem::discriminant(self) == std::mem::discriminant(other)
742 }
743 (Self::Clone { .. }, Self::CreateIndex { .. }) => {
744 std::mem::discriminant(self) == std::mem::discriminant(other)
745 }
746 (Self::Clone { .. }, Self::Rewrite { .. }) => {
747 std::mem::discriminant(self) == std::mem::discriminant(other)
748 }
749 (Self::Clone { .. }, Self::Merge { .. }) => {
750 std::mem::discriminant(self) == std::mem::discriminant(other)
751 }
752 (Self::Clone { .. }, Self::Restore { .. }) => {
753 std::mem::discriminant(self) == std::mem::discriminant(other)
754 }
755 (Self::Clone { .. }, Self::ReserveFragments { .. }) => {
756 std::mem::discriminant(self) == std::mem::discriminant(other)
757 }
758 (Self::Clone { .. }, Self::Update { .. }) => {
759 std::mem::discriminant(self) == std::mem::discriminant(other)
760 }
761 (Self::Clone { .. }, Self::Project { .. }) => {
762 std::mem::discriminant(self) == std::mem::discriminant(other)
763 }
764 (Self::Clone { .. }, Self::UpdateConfig { .. }) => {
765 std::mem::discriminant(self) == std::mem::discriminant(other)
766 }
767 (Self::Clone { .. }, Self::DataReplacement { .. }) => {
768 std::mem::discriminant(self) == std::mem::discriminant(other)
769 }
770 (Self::Clone { .. }, Self::UpdateMemWalState { .. }) => {
771 std::mem::discriminant(self) == std::mem::discriminant(other)
772 }
773
774 (Self::UpdateBases { new_bases: a }, Self::UpdateBases { new_bases: b }) => {
775 compare_vec(a, b)
776 }
777
778 (Self::UpdateBases { .. }, Self::Append { .. }) => {
779 std::mem::discriminant(self) == std::mem::discriminant(other)
780 }
781 (Self::UpdateBases { .. }, Self::Delete { .. }) => {
782 std::mem::discriminant(self) == std::mem::discriminant(other)
783 }
784 (Self::UpdateBases { .. }, Self::Overwrite { .. }) => {
785 std::mem::discriminant(self) == std::mem::discriminant(other)
786 }
787 (Self::UpdateBases { .. }, Self::CreateIndex { .. }) => {
788 std::mem::discriminant(self) == std::mem::discriminant(other)
789 }
790 (Self::UpdateBases { .. }, Self::Rewrite { .. }) => {
791 std::mem::discriminant(self) == std::mem::discriminant(other)
792 }
793 (Self::UpdateBases { .. }, Self::Merge { .. }) => {
794 std::mem::discriminant(self) == std::mem::discriminant(other)
795 }
796 (Self::UpdateBases { .. }, Self::Restore { .. }) => {
797 std::mem::discriminant(self) == std::mem::discriminant(other)
798 }
799 (Self::UpdateBases { .. }, Self::ReserveFragments { .. }) => {
800 std::mem::discriminant(self) == std::mem::discriminant(other)
801 }
802 (Self::UpdateBases { .. }, Self::Update { .. }) => {
803 std::mem::discriminant(self) == std::mem::discriminant(other)
804 }
805 (Self::UpdateBases { .. }, Self::Project { .. }) => {
806 std::mem::discriminant(self) == std::mem::discriminant(other)
807 }
808 (Self::UpdateBases { .. }, Self::UpdateConfig { .. }) => {
809 std::mem::discriminant(self) == std::mem::discriminant(other)
810 }
811 (Self::UpdateBases { .. }, Self::DataReplacement { .. }) => {
812 std::mem::discriminant(self) == std::mem::discriminant(other)
813 }
814 (Self::UpdateBases { .. }, Self::UpdateMemWalState { .. }) => {
815 std::mem::discriminant(self) == std::mem::discriminant(other)
816 }
817 (Self::UpdateBases { .. }, Self::Clone { .. }) => {
818 std::mem::discriminant(self) == std::mem::discriminant(other)
819 }
820
821 (Self::Append { .. }, Self::UpdateBases { .. }) => {
822 std::mem::discriminant(self) == std::mem::discriminant(other)
823 }
824 (Self::Delete { .. }, Self::UpdateBases { .. }) => {
825 std::mem::discriminant(self) == std::mem::discriminant(other)
826 }
827 (Self::Overwrite { .. }, Self::UpdateBases { .. }) => {
828 std::mem::discriminant(self) == std::mem::discriminant(other)
829 }
830 (Self::CreateIndex { .. }, Self::UpdateBases { .. }) => {
831 std::mem::discriminant(self) == std::mem::discriminant(other)
832 }
833 (Self::Rewrite { .. }, Self::UpdateBases { .. }) => {
834 std::mem::discriminant(self) == std::mem::discriminant(other)
835 }
836 (Self::Merge { .. }, Self::UpdateBases { .. }) => {
837 std::mem::discriminant(self) == std::mem::discriminant(other)
838 }
839 (Self::Restore { .. }, Self::UpdateBases { .. }) => {
840 std::mem::discriminant(self) == std::mem::discriminant(other)
841 }
842 (Self::ReserveFragments { .. }, Self::UpdateBases { .. }) => {
843 std::mem::discriminant(self) == std::mem::discriminant(other)
844 }
845 (Self::Update { .. }, Self::UpdateBases { .. }) => {
846 std::mem::discriminant(self) == std::mem::discriminant(other)
847 }
848 (Self::Project { .. }, Self::UpdateBases { .. }) => {
849 std::mem::discriminant(self) == std::mem::discriminant(other)
850 }
851 (Self::UpdateConfig { .. }, Self::UpdateBases { .. }) => {
852 std::mem::discriminant(self) == std::mem::discriminant(other)
853 }
854 (Self::DataReplacement { .. }, Self::UpdateBases { .. }) => {
855 std::mem::discriminant(self) == std::mem::discriminant(other)
856 }
857 (Self::UpdateMemWalState { .. }, Self::UpdateBases { .. }) => {
858 std::mem::discriminant(self) == std::mem::discriminant(other)
859 }
860 (Self::Clone { .. }, Self::UpdateBases { .. }) => {
861 std::mem::discriminant(self) == std::mem::discriminant(other)
862 }
863 (Self::DataOverlay { groups: a }, Self::DataOverlay { groups: b }) => compare_vec(a, b),
864 (Self::DataOverlay { .. }, _) | (_, Self::DataOverlay { .. }) => false,
865 }
866 }
867}
868
869impl Operation {
870 fn get_upsert_config_keys(&self) -> Vec<String> {
872 match self {
873 Self::Overwrite {
874 config_upsert_values: Some(upsert_values),
875 ..
876 } => {
877 let vec: Vec<String> = upsert_values.keys().cloned().collect();
878 vec
879 }
880 Self::UpdateConfig {
881 config_updates: Some(config_updates),
882 ..
883 } => config_updates
884 .update_entries
885 .iter()
886 .filter_map(|entry| {
887 if entry.value.is_some() {
888 Some(entry.key.clone())
889 } else {
890 None
891 }
892 })
893 .collect(),
894 _ => Vec::<String>::new(),
895 }
896 }
897
898 fn get_delete_config_keys(&self) -> Vec<String> {
900 match self {
901 Self::UpdateConfig {
902 config_updates: Some(config_updates),
903 ..
904 } => config_updates
905 .update_entries
906 .iter()
907 .filter_map(|entry| {
908 if entry.value.is_none() {
909 Some(entry.key.clone())
910 } else {
911 None
912 }
913 })
914 .collect(),
915 _ => Vec::<String>::new(),
916 }
917 }
918
919 pub fn modifies_same_metadata(&self, other: &Self) -> bool {
920 match (self, other) {
921 (
922 Self::UpdateConfig {
923 table_metadata_updates,
924 schema_metadata_updates,
925 field_metadata_updates,
926 ..
927 },
928 Self::UpdateConfig {
929 table_metadata_updates: other_table_metadata,
930 schema_metadata_updates: other_schema_metadata,
931 field_metadata_updates: other_field_metadata,
932 ..
933 },
934 ) => {
935 if Self::update_maps_conflict(
936 table_metadata_updates.as_ref(),
937 other_table_metadata.as_ref(),
938 ) {
939 return true;
940 }
941 if schema_metadata_updates.is_some() && other_schema_metadata.is_some() {
942 return true;
943 }
944 if !field_metadata_updates.is_empty() && !other_field_metadata.is_empty() {
945 for field in field_metadata_updates.keys() {
946 if other_field_metadata.contains_key(field) {
947 return true;
948 }
949 }
950 }
951 false
952 }
953 _ => false,
954 }
955 }
956
957 fn update_maps_conflict(left: Option<&UpdateMap>, right: Option<&UpdateMap>) -> bool {
958 let (Some(left), Some(right)) = (left, right) else {
959 return false;
960 };
961 if left.replace || right.replace {
962 return true;
963 }
964 let left_keys = left
965 .update_entries
966 .iter()
967 .map(|entry| entry.key.as_str())
968 .collect::<HashSet<_>>();
969 right
970 .update_entries
971 .iter()
972 .any(|entry| left_keys.contains(entry.key.as_str()))
973 }
974
975 pub fn upsert_key_conflict(&self, other: &Self) -> bool {
977 let self_upsert_keys = self.get_upsert_config_keys();
978 let other_upsert_keys = other.get_upsert_config_keys();
979
980 let self_delete_keys = self.get_delete_config_keys();
981 let other_delete_keys = other.get_delete_config_keys();
982
983 self_upsert_keys
984 .iter()
985 .any(|x| other_upsert_keys.contains(x) || other_delete_keys.contains(x))
986 || other_upsert_keys
987 .iter()
988 .any(|x| self_upsert_keys.contains(x) || self_delete_keys.contains(x))
989 }
990}
991
992#[cfg(test)]
993mod tests {
994 use super::*;
995 use crate::transaction::test_support::overlay_with_field;
996 use crate::transaction::{DataOverlayGroup, UpdateMapEntry};
997 use std::collections::HashMap;
998
999 fn table_metadata_update(entries: Vec<(&str, Option<&str>)>, replace: bool) -> Operation {
1000 Operation::UpdateConfig {
1001 config_updates: None,
1002 table_metadata_updates: Some(UpdateMap {
1003 update_entries: entries.into_iter().map(UpdateMapEntry::from).collect(),
1004 replace,
1005 }),
1006 schema_metadata_updates: None,
1007 field_metadata_updates: HashMap::new(),
1008 }
1009 }
1010
1011 #[test]
1012 fn test_table_metadata_conflicts_on_same_key() {
1013 let left = table_metadata_update(vec![("key", Some("1"))], false);
1014 let same_key = table_metadata_update(vec![("key", Some("2"))], false);
1015 let different_key = table_metadata_update(vec![("other", Some("2"))], false);
1016 let replace = table_metadata_update(vec![("other", Some("2"))], true);
1017
1018 assert!(left.modifies_same_metadata(&same_key));
1019 assert!(!left.modifies_same_metadata(&different_key));
1020 assert!(left.modifies_same_metadata(&replace));
1021 }
1022
1023 #[test]
1024 fn test_data_overlay_operation_eq() {
1025 let overlay = |field: i32| Operation::DataOverlay {
1026 groups: vec![DataOverlayGroup {
1027 fragment_id: 0,
1028 overlays: vec![overlay_with_field(field, 1)],
1029 }],
1030 };
1031 assert_eq!(overlay(1), overlay(1));
1033 assert_ne!(overlay(1), overlay(2));
1034 let rewrite = Operation::Rewrite {
1036 groups: vec![],
1037 rewritten_indices: vec![],
1038 frag_reuse_index: None,
1039 };
1040 assert_ne!(overlay(1), rewrite);
1041 }
1042}