Skip to content

Commit cbd20d7

Browse files
committed
Method to form the union of TableCollections
1 parent 55391fa commit cbd20d7

File tree

14 files changed

+1191
-89
lines changed

14 files changed

+1191
-89
lines changed

c/CHANGELOG.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ In development.
3939

4040
**New features**
4141

42+
- New methods to perform set operations on table collections.
43+
``tsk_table_collection_subset`` subsets and reorders table collections by nodes
44+
(:user:`mufernando`, :user:`petrelharp`, :pr:`663`, :pr:`690`).
45+
``tsk_table_collection_union`` forms the node-wise union of two table collections
46+
(:user:`mufernando`, :user:`petrelharp`, :issue:`381`, :pr:`623`).
47+
4248
- Mutations now have an optional double-precision floating-point ``time`` column.
4349
If not specified, this defaults to a particular NaN value (``TSK_UNKNOWN_TIME``)
4450
indicating that the time is unknown. For a tree sequence to be considered valid

c/tests/test_tables.c

Lines changed: 246 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,10 +3514,10 @@ test_table_collection_subset_with_options(tsk_flags_t options)
35143514
// four nodes from two diploids; the first is from pop 0
35153515
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
35163516
CU_ASSERT_FATAL(ret >= 0);
3517-
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
3517+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 1.0, 0, 0, NULL, 0);
35183518
CU_ASSERT_FATAL(ret >= 0);
35193519
ret = tsk_node_table_add_row(
3520-
&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, TSK_NULL, 1, NULL, 0);
3520+
&tables.nodes, TSK_NODE_IS_SAMPLE, 2.0, TSK_NULL, 1, NULL, 0);
35213521
CU_ASSERT_FATAL(ret >= 0);
35223522
ret = tsk_node_table_add_row(
35233523
&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, TSK_NULL, 1, NULL, 0);
@@ -3544,6 +3544,8 @@ test_table_collection_subset_with_options(tsk_flags_t options)
35443544
ret = tsk_mutation_table_add_row(
35453545
&tables.mutations, 1, 1, TSK_NULL, NAN, NULL, 0, NULL, 0);
35463546
CU_ASSERT_FATAL(ret >= 0);
3547+
ret = tsk_table_collection_build_index(&tables, 0);
3548+
CU_ASSERT_EQUAL_FATAL(ret, 0);
35473549

35483550
// empty nodes should get empty tables
35493551
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT | options);
@@ -3597,16 +3599,17 @@ test_table_collection_subset_errors(void)
35973599

35983600
ret = tsk_table_collection_init(&tables, 0);
35993601
CU_ASSERT_EQUAL_FATAL(ret, 0);
3602+
tables.sequence_length = 1;
36003603
ret = tsk_table_collection_init(&tables_copy, 0);
36013604
CU_ASSERT_EQUAL_FATAL(ret, 0);
36023605

36033606
// four nodes from two diploids; the first is from pop 0
36043607
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
36053608
CU_ASSERT_FATAL(ret >= 0);
3606-
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
3609+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 1.0, 0, 0, NULL, 0);
36073610
CU_ASSERT_FATAL(ret >= 0);
36083611
ret = tsk_node_table_add_row(
3609-
&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, TSK_NULL, 1, NULL, 0);
3612+
&tables.nodes, TSK_NODE_IS_SAMPLE, 2.0, TSK_NULL, 1, NULL, 0);
36103613
CU_ASSERT_FATAL(ret >= 0);
36113614
ret = tsk_node_table_add_row(
36123615
&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, TSK_NULL, 1, NULL, 0);
@@ -3619,6 +3622,8 @@ test_table_collection_subset_errors(void)
36193622
CU_ASSERT_FATAL(ret >= 0);
36203623
ret = tsk_edge_table_add_row(&tables.edges, 0.0, 1.0, 1, 0, NULL, 0);
36213624
CU_ASSERT_FATAL(ret >= 0);
3625+
ret = tsk_table_collection_build_index(&tables, 0);
3626+
CU_ASSERT_EQUAL_FATAL(ret, 0);
36223627

36233628
/* Migrations are not supported */
36243629
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
@@ -3629,17 +3634,250 @@ test_table_collection_subset_errors(void)
36293634
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_MIGRATIONS_NOT_SUPPORTED);
36303635

36313636
// test out of bounds nodes
3637+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3638+
CU_ASSERT_EQUAL_FATAL(ret, 0);
36323639
nodes[0] = -1;
3633-
ret = tsk_table_collection_subset(&tables, nodes, 4);
3640+
ret = tsk_table_collection_subset(&tables_copy, nodes, 4);
36343641
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_NODE_OUT_OF_BOUNDS);
36353642
nodes[0] = 6;
3636-
ret = tsk_table_collection_subset(&tables, nodes, 4);
3643+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3644+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3645+
ret = tsk_table_collection_subset(&tables_copy, nodes, 4);
36373646
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_NODE_OUT_OF_BOUNDS);
36383647

3648+
// check integrity
3649+
nodes[0] = 0;
3650+
nodes[1] = 1;
3651+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3652+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3653+
ret = tsk_node_table_truncate(&tables_copy.nodes, 3);
3654+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3655+
ret = tsk_node_table_add_row(
3656+
&tables_copy.nodes, TSK_NODE_IS_SAMPLE, 0.0, -2, 0, NULL, 0);
3657+
CU_ASSERT_FATAL(ret >= 0);
3658+
ret = tsk_table_collection_subset(&tables_copy, nodes, 4);
3659+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_POPULATION_OUT_OF_BOUNDS);
3660+
36393661
tsk_table_collection_free(&tables);
36403662
tsk_table_collection_free(&tables_copy);
36413663
}
36423664

3665+
static void
3666+
test_table_collection_union(void)
3667+
{
3668+
int ret;
3669+
tsk_table_collection_t tables;
3670+
tsk_table_collection_t tables_empty;
3671+
tsk_table_collection_t tables_copy;
3672+
tsk_id_t node_mapping[3];
3673+
3674+
memset(node_mapping, 0xff, sizeof(node_mapping));
3675+
3676+
ret = tsk_table_collection_init(&tables, 0);
3677+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3678+
tables.sequence_length = 1;
3679+
ret = tsk_table_collection_init(&tables_empty, 0);
3680+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3681+
tables_empty.sequence_length = 1;
3682+
ret = tsk_table_collection_init(&tables_copy, 0);
3683+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3684+
3685+
// does not error on empty tables
3686+
ret = tsk_table_collection_union(
3687+
&tables, &tables_empty, node_mapping, TSK_UNION_NO_CHECK_SHARED);
3688+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3689+
3690+
// three nodes, two pop, three ind, two edge, two site, two mut
3691+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
3692+
CU_ASSERT_FATAL(ret >= 0);
3693+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 1, 1, NULL, 0);
3694+
CU_ASSERT_FATAL(ret >= 0);
3695+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.5, 1, 2, NULL, 0);
3696+
CU_ASSERT_FATAL(ret >= 0);
3697+
ret = tsk_individual_table_add_row(&tables.individuals, 0, NULL, 0, NULL, 0);
3698+
CU_ASSERT_FATAL(ret >= 0);
3699+
ret = tsk_individual_table_add_row(&tables.individuals, 0, NULL, 0, NULL, 0);
3700+
CU_ASSERT_FATAL(ret >= 0);
3701+
ret = tsk_individual_table_add_row(&tables.individuals, 0, NULL, 0, NULL, 0);
3702+
CU_ASSERT_FATAL(ret >= 0);
3703+
ret = tsk_population_table_add_row(&tables.populations, NULL, 0);
3704+
CU_ASSERT_FATAL(ret >= 0);
3705+
ret = tsk_population_table_add_row(&tables.populations, NULL, 0);
3706+
CU_ASSERT_FATAL(ret >= 0);
3707+
ret = tsk_edge_table_add_row(&tables.edges, 0.0, 1.0, 2, 0, NULL, 0);
3708+
CU_ASSERT_FATAL(ret >= 0);
3709+
ret = tsk_edge_table_add_row(&tables.edges, 0.0, 1.0, 2, 1, NULL, 0);
3710+
CU_ASSERT_FATAL(ret >= 0);
3711+
ret = tsk_site_table_add_row(&tables.sites, 0.4, "T", 1, NULL, 0);
3712+
CU_ASSERT_FATAL(ret >= 0);
3713+
ret = tsk_site_table_add_row(&tables.sites, 0.2, "A", 1, NULL, 0);
3714+
CU_ASSERT_FATAL(ret >= 0);
3715+
ret = tsk_mutation_table_add_row(
3716+
&tables.mutations, 0, 0, TSK_NULL, TSK_UNKNOWN_TIME, NULL, 0, NULL, 0);
3717+
ret = tsk_mutation_table_add_row(
3718+
&tables.mutations, 1, 1, TSK_NULL, TSK_UNKNOWN_TIME, NULL, 0, NULL, 0);
3719+
CU_ASSERT_FATAL(ret >= 0);
3720+
ret = tsk_table_collection_build_index(&tables, 0);
3721+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3722+
ret = tsk_table_collection_sort(&tables, NULL, 0);
3723+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3724+
3725+
// union with empty should not change
3726+
// other is empty
3727+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3728+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3729+
ret = tsk_table_collection_union(
3730+
&tables_copy, &tables_empty, node_mapping, TSK_UNION_NO_CHECK_SHARED);
3731+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &tables_copy));
3732+
// self is empty
3733+
ret = tsk_table_collection_clear(&tables_copy);
3734+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3735+
ret = tsk_table_collection_union(
3736+
&tables_copy, &tables, node_mapping, TSK_UNION_NO_CHECK_SHARED);
3737+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3738+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &tables_copy));
3739+
3740+
// union all shared nodes + subset original nodes = original table
3741+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3742+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3743+
ret = tsk_table_collection_union(
3744+
&tables_copy, &tables, node_mapping, TSK_UNION_NO_CHECK_SHARED);
3745+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3746+
node_mapping[0] = 0;
3747+
node_mapping[1] = 1;
3748+
node_mapping[2] = 2;
3749+
ret = tsk_table_collection_subset(&tables_copy, node_mapping, 3);
3750+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3751+
CU_ASSERT_FATAL(tsk_table_collection_equals(&tables, &tables_copy));
3752+
3753+
// union with one shared node
3754+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3755+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3756+
node_mapping[0] = TSK_NULL;
3757+
node_mapping[1] = TSK_NULL;
3758+
node_mapping[2] = 2;
3759+
ret = tsk_table_collection_union(&tables_copy, &tables, node_mapping, 0);
3760+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3761+
CU_ASSERT_EQUAL_FATAL(
3762+
tables_copy.populations.num_rows, tables.populations.num_rows + 2);
3763+
CU_ASSERT_EQUAL_FATAL(
3764+
tables_copy.individuals.num_rows, tables.individuals.num_rows + 2);
3765+
CU_ASSERT_EQUAL_FATAL(tables_copy.nodes.num_rows, tables.nodes.num_rows + 2);
3766+
CU_ASSERT_EQUAL_FATAL(tables_copy.edges.num_rows, tables.edges.num_rows + 2);
3767+
CU_ASSERT_EQUAL_FATAL(tables_copy.sites.num_rows, tables.sites.num_rows);
3768+
CU_ASSERT_EQUAL_FATAL(tables_copy.mutations.num_rows, tables.mutations.num_rows + 2);
3769+
3770+
// union with one shared node, but no add pop
3771+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3772+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3773+
node_mapping[0] = TSK_NULL;
3774+
node_mapping[1] = TSK_NULL;
3775+
node_mapping[2] = 2;
3776+
ret = tsk_table_collection_union(
3777+
&tables_copy, &tables, node_mapping, TSK_UNION_NO_ADD_POP);
3778+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3779+
CU_ASSERT_EQUAL_FATAL(tables_copy.populations.num_rows, tables.populations.num_rows);
3780+
CU_ASSERT_EQUAL_FATAL(
3781+
tables_copy.individuals.num_rows, tables.individuals.num_rows + 2);
3782+
CU_ASSERT_EQUAL_FATAL(tables_copy.nodes.num_rows, tables.nodes.num_rows + 2);
3783+
CU_ASSERT_EQUAL_FATAL(tables_copy.edges.num_rows, tables.edges.num_rows + 2);
3784+
CU_ASSERT_EQUAL_FATAL(tables_copy.sites.num_rows, tables.sites.num_rows);
3785+
CU_ASSERT_EQUAL_FATAL(tables_copy.mutations.num_rows, tables.mutations.num_rows + 2);
3786+
3787+
tsk_table_collection_free(&tables_copy);
3788+
tsk_table_collection_free(&tables_empty);
3789+
tsk_table_collection_free(&tables);
3790+
}
3791+
3792+
static void
3793+
test_table_collection_union_errors(void)
3794+
{
3795+
int ret;
3796+
tsk_table_collection_t tables;
3797+
tsk_table_collection_t tables_copy;
3798+
tsk_id_t node_mapping[] = { 0, 1 };
3799+
3800+
ret = tsk_table_collection_init(&tables, 0);
3801+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3802+
tables.sequence_length = 1;
3803+
ret = tsk_table_collection_init(&tables_copy, 0);
3804+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3805+
3806+
// two nodes, two pop, two ind, one edge, one site, one mut
3807+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, 0, 0, NULL, 0);
3808+
CU_ASSERT_FATAL(ret >= 0);
3809+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.5, 1, 1, NULL, 0);
3810+
CU_ASSERT_FATAL(ret >= 0);
3811+
ret = tsk_individual_table_add_row(&tables.individuals, 0, NULL, 0, NULL, 0);
3812+
CU_ASSERT_FATAL(ret >= 0);
3813+
ret = tsk_individual_table_add_row(&tables.individuals, 0, NULL, 0, NULL, 0);
3814+
CU_ASSERT_FATAL(ret >= 0);
3815+
ret = tsk_population_table_add_row(&tables.populations, NULL, 0);
3816+
CU_ASSERT_FATAL(ret >= 0);
3817+
ret = tsk_population_table_add_row(&tables.populations, NULL, 0);
3818+
CU_ASSERT_FATAL(ret >= 0);
3819+
ret = tsk_edge_table_add_row(&tables.edges, 0.0, 1.0, 1, 0, NULL, 0);
3820+
CU_ASSERT_FATAL(ret >= 0);
3821+
ret = tsk_site_table_add_row(&tables.sites, 0.2, "A", 1, NULL, 0);
3822+
CU_ASSERT_FATAL(ret >= 0);
3823+
ret = tsk_mutation_table_add_row(
3824+
&tables.mutations, 0, 0, TSK_NULL, TSK_UNKNOWN_TIME, NULL, 0, NULL, 0);
3825+
CU_ASSERT_FATAL(ret >= 0);
3826+
3827+
// trigger diff histories error
3828+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3829+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3830+
ret = tsk_mutation_table_add_row(
3831+
&tables_copy.mutations, 0, 1, TSK_NULL, TSK_UNKNOWN_TIME, NULL, 0, NULL, 0);
3832+
CU_ASSERT_FATAL(ret >= 0);
3833+
ret = tsk_table_collection_union(&tables_copy, &tables, node_mapping, 0);
3834+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_UNION_DIFF_HISTORIES);
3835+
3836+
// Migrations are not supported
3837+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3838+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3839+
tsk_migration_table_add_row(&tables_copy.migrations, 0, 1, 0, 0, 0, 0, NULL, 0);
3840+
CU_ASSERT_EQUAL_FATAL(tables_copy.migrations.num_rows, 1);
3841+
ret = tsk_table_collection_union(
3842+
&tables_copy, &tables, node_mapping, TSK_UNION_NO_CHECK_SHARED);
3843+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_MIGRATIONS_NOT_SUPPORTED);
3844+
3845+
// unsuported union - child shared parent not shared
3846+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3847+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3848+
node_mapping[0] = 0;
3849+
node_mapping[1] = TSK_NULL;
3850+
ret = tsk_table_collection_union(
3851+
&tables_copy, &tables, node_mapping, TSK_UNION_NO_ADD_POP);
3852+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_UNION_NOT_SUPPORTED);
3853+
3854+
// test out of bounds node_mapping
3855+
node_mapping[0] = -4;
3856+
node_mapping[1] = 6;
3857+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3858+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3859+
ret = tsk_table_collection_union(&tables_copy, &tables, node_mapping, 0);
3860+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_UNION_BAD_MAP);
3861+
3862+
// check integrity
3863+
node_mapping[0] = 0;
3864+
node_mapping[1] = 1;
3865+
ret = tsk_node_table_add_row(
3866+
&tables_copy.nodes, TSK_NODE_IS_SAMPLE, 0.0, -2, 0, NULL, 0);
3867+
CU_ASSERT_FATAL(ret >= 0);
3868+
ret = tsk_table_collection_union(&tables_copy, &tables, node_mapping, 0);
3869+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_POPULATION_OUT_OF_BOUNDS);
3870+
ret = tsk_table_collection_copy(&tables, &tables_copy, TSK_NO_INIT);
3871+
CU_ASSERT_EQUAL_FATAL(ret, 0);
3872+
ret = tsk_node_table_add_row(&tables.nodes, TSK_NODE_IS_SAMPLE, 0.0, -2, 0, NULL, 0);
3873+
CU_ASSERT_FATAL(ret >= 0);
3874+
ret = tsk_table_collection_union(&tables, &tables_copy, node_mapping, 0);
3875+
CU_ASSERT_EQUAL_FATAL(ret, TSK_ERR_POPULATION_OUT_OF_BOUNDS);
3876+
3877+
tsk_table_collection_free(&tables_copy);
3878+
tsk_table_collection_free(&tables);
3879+
}
3880+
36433881
int
36443882
main(int argc, char **argv)
36453883
{
@@ -3688,6 +3926,8 @@ main(int argc, char **argv)
36883926
test_table_collection_check_integrity },
36893927
{ "test_table_collection_subset", test_table_collection_subset },
36903928
{ "test_table_collection_subset_errors", test_table_collection_subset_errors },
3929+
{ "test_table_collection_union", test_table_collection_union },
3930+
{ "test_table_collection_union_errors", test_table_collection_union_errors },
36913931
{ NULL, NULL },
36923932
};
36933933

c/tskit/core.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,10 @@ tsk_strerror_internal(int err)
348348
case TSK_ERR_NONBINARY_MUTATIONS_UNSUPPORTED:
349349
ret = "Only binary mutations are supported for this operation";
350350
break;
351+
case TSK_ERR_UNION_NOT_SUPPORTED:
352+
ret = "Union is not supported for cases where there is non-shared"
353+
"history older than the shared history of the two Table Collections";
354+
break;
351355

352356
/* Stats errors */
353357
case TSK_ERR_BAD_NUM_WINDOWS:
@@ -437,6 +441,16 @@ tsk_strerror_internal(int err)
437441
case TSK_ERR_TOO_MANY_VALUES:
438442
ret = "Too many values to compress";
439443
break;
444+
445+
/* Union errors */
446+
case TSK_ERR_UNION_BAD_MAP:
447+
ret = "Node map contains an entry of a node not present in this table "
448+
"collection.";
449+
break;
450+
case TSK_ERR_UNION_DIFF_HISTORIES:
451+
// histories could be equivalent, because subset does not reorder
452+
// edges (if not sorted) or mutations.
453+
ret = "Shared portions of the tree sequences are not equal.";
440454
}
441455
return ret;
442456
}

c/tskit/core.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ not found in the file.
248248
#define TSK_ERR_SORT_OFFSET_NOT_SUPPORTED -803
249249
#define TSK_ERR_NONBINARY_MUTATIONS_UNSUPPORTED -804
250250
#define TSK_ERR_MIGRATIONS_NOT_SUPPORTED -805
251+
#define TSK_ERR_UNION_NOT_SUPPORTED -806
251252

252253
/* Stats errors */
253254
#define TSK_ERR_BAD_NUM_WINDOWS -900
@@ -284,6 +285,11 @@ not found in the file.
284285
#define TSK_ERR_MATCH_IMPOSSIBLE -1301
285286
#define TSK_ERR_BAD_COMPRESSED_MATRIX_NODE -1302
286287
#define TSK_ERR_TOO_MANY_VALUES -1303
288+
289+
/* Union errors */
290+
#define TSK_ERR_UNION_BAD_MAP -1400
291+
#define TSK_ERR_UNION_DIFF_HISTORIES -1401
292+
287293
// clang-format on
288294

289295
/* This bit is 0 for any errors originating from kastore */

0 commit comments

Comments
 (0)