Skip to content

Commit 301243a

Browse files
committed
#1169 Fix issue with overcounting the number of nodata terms in a query with OR terms
1 parent bb65f68 commit 301243a

File tree

6 files changed

+111
-20
lines changed

6 files changed

+111
-20
lines changed

flecs.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11198,17 +11198,20 @@ ecs_term_t* flecs_filter_or_other_type(
1119811198
if (f->terms[t].oper != EcsOr) {
1119911199
break;
1120011200
}
11201+
1120111202
first = &f->terms[t];
1120211203
}
1120311204

1120411205
if (first) {
1120511206
ecs_world_t *world = f->world;
1120611207
const ecs_type_info_t *first_type;
11208+
1120711209
if (first->idr) {
1120811210
first_type = first->idr->type_info;
1120911211
} else {
1121011212
first_type = ecs_get_type_info(world, first->id);
1121111213
}
11214+
1121211215
const ecs_type_info_t *term_type;
1121311216
if (term->idr) {
1121411217
term_type = term->idr->type_info;
@@ -11219,6 +11222,7 @@ ecs_term_t* flecs_filter_or_other_type(
1121911222
if (first_type == term_type) {
1122011223
return NULL;
1122111224
}
11225+
1122211226
return first;
1122311227
} else {
1122411228
return NULL;
@@ -11328,7 +11332,9 @@ int ecs_filter_finalize(
1132811332
ecs_term_t *first = flecs_filter_or_other_type(f, i);
1132911333
if (first) {
1133011334
if (first == &term[-1]) {
11331-
filter_terms ++;
11335+
if (!(term[-1].flags & EcsTermNoData)) {
11336+
filter_terms ++;
11337+
}
1133211338
}
1133311339
filter_term = true;
1133411340
}
@@ -13297,9 +13303,11 @@ bool ecs_filter_next_instanced(
1329713303

1329813304
/* Match the remainder of the terms */
1329913305
int32_t skip_term = pivot_term;
13300-
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
13301-
skip_term = -1;
13302-
iter->matches_left = 1;
13306+
if (pivot_term != -1) {
13307+
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
13308+
skip_term = -1;
13309+
iter->matches_left = 1;
13310+
}
1330313311
}
1330413312

1330513313
match = flecs_filter_match_table(world, filter, table,
@@ -13351,18 +13359,18 @@ bool ecs_filter_next_instanced(
1335113359
}
1335213360

1335313361
int32_t t, term_count = filter->term_count;
13354-
ecs_term_t *term = NULL;
13362+
ecs_term_t *cur_term = NULL;
1335513363
for (t = 0; t < term_count; t ++) {
1335613364
if (filter->terms[t].field_index == i) {
13357-
term = &filter->terms[t];
13365+
cur_term = &filter->terms[t];
1335813366
break;
1335913367
}
1336013368
}
1336113369

1336213370
ecs_assert(term != NULL, ECS_INTERNAL_ERROR, NULL);
1336313371

1336413372
it->columns[i] = column + 1;
13365-
flecs_term_match_table(world, term, table,
13373+
flecs_term_match_table(world, cur_term, table,
1336613374
&it->ids[i], &it->columns[i], &it->sources[i],
1336713375
&it->match_indices[i], false, it->flags);
1336813376

src/filter.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,17 +1148,20 @@ ecs_term_t* flecs_filter_or_other_type(
11481148
if (f->terms[t].oper != EcsOr) {
11491149
break;
11501150
}
1151+
11511152
first = &f->terms[t];
11521153
}
11531154

11541155
if (first) {
11551156
ecs_world_t *world = f->world;
11561157
const ecs_type_info_t *first_type;
1158+
11571159
if (first->idr) {
11581160
first_type = first->idr->type_info;
11591161
} else {
11601162
first_type = ecs_get_type_info(world, first->id);
11611163
}
1164+
11621165
const ecs_type_info_t *term_type;
11631166
if (term->idr) {
11641167
term_type = term->idr->type_info;
@@ -1169,6 +1172,7 @@ ecs_term_t* flecs_filter_or_other_type(
11691172
if (first_type == term_type) {
11701173
return NULL;
11711174
}
1175+
11721176
return first;
11731177
} else {
11741178
return NULL;
@@ -1278,7 +1282,9 @@ int ecs_filter_finalize(
12781282
ecs_term_t *first = flecs_filter_or_other_type(f, i);
12791283
if (first) {
12801284
if (first == &term[-1]) {
1281-
filter_terms ++;
1285+
if (!(term[-1].flags & EcsTermNoData)) {
1286+
filter_terms ++;
1287+
}
12821288
}
12831289
filter_term = true;
12841290
}
@@ -3247,9 +3253,11 @@ bool ecs_filter_next_instanced(
32473253

32483254
/* Match the remainder of the terms */
32493255
int32_t skip_term = pivot_term;
3250-
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
3251-
skip_term = -1;
3252-
iter->matches_left = 1;
3256+
if (pivot_term != -1) {
3257+
if (ecs_id_is_wildcard(filter->terms[pivot_term].id)) {
3258+
skip_term = -1;
3259+
iter->matches_left = 1;
3260+
}
32533261
}
32543262

32553263
match = flecs_filter_match_table(world, filter, table,
@@ -3301,18 +3309,18 @@ bool ecs_filter_next_instanced(
33013309
}
33023310

33033311
int32_t t, term_count = filter->term_count;
3304-
ecs_term_t *term = NULL;
3312+
ecs_term_t *cur_term = NULL;
33053313
for (t = 0; t < term_count; t ++) {
33063314
if (filter->terms[t].field_index == i) {
3307-
term = &filter->terms[t];
3315+
cur_term = &filter->terms[t];
33083316
break;
33093317
}
33103318
}
33113319

33123320
ecs_assert(term != NULL, ECS_INTERNAL_ERROR, NULL);
33133321

33143322
it->columns[i] = column + 1;
3315-
flecs_term_match_table(world, term, table,
3323+
flecs_term_match_table(world, cur_term, table,
33163324
&it->ids[i], &it->columns[i], &it->sources[i],
33173325
&it->match_indices[i], false, it->flags);
33183326

test/api/project.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,9 @@
13101310
"filter_iter_3_or",
13111311
"filter_iter_2_or_other_type",
13121312
"filter_iter_2_or_same_type",
1313-
"filter_or_w_wildcard",
1313+
"filter_iter_or_w_wildcard",
1314+
"filer_iter_or_w_component_and_tag",
1315+
"filer_iter_or_w_tag_and_component",
13141316
"filter_iter_1_component",
13151317
"filter_iter_2_components",
13161318
"filter_iter_pair_id",

test/api/src/Filter.c

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4643,7 +4643,7 @@ void Filter_filter_iter_2_or_same_type(void) {
46434643
ecs_fini(world);
46444644
}
46454645

4646-
void Filter_filter_or_w_wildcard(void) {
4646+
void Filter_filter_iter_or_w_wildcard(void) {
46474647
ecs_world_t *world = ecs_mini();
46484648

46494649
ECS_TAG(world, Rel);
@@ -4687,6 +4687,68 @@ void Filter_filter_or_w_wildcard(void) {
46874687
ecs_fini(world);
46884688
}
46894689

4690+
void Filter_filer_iter_or_w_component_and_tag(void) {
4691+
ecs_world_t *world = ecs_mini();
4692+
4693+
ECS_COMPONENT(world, Position);
4694+
ECS_TAG(world, TagA);
4695+
4696+
ecs_filter_t *q = ecs_filter(world, {
4697+
.terms = {
4698+
{ ecs_id(Position), .oper = EcsOr },
4699+
{ TagA }
4700+
}
4701+
});
4702+
4703+
test_assert(q != NULL);
4704+
4705+
ecs_entity_t e = ecs_new_id(world);
4706+
ecs_set(world, e, Position, {10, 20});
4707+
ecs_add(world, e, TagA);
4708+
4709+
ecs_iter_t it = ecs_filter_iter(world, q);
4710+
test_bool(true, ecs_filter_next(&it));
4711+
test_int(1, it.count);
4712+
test_uint(e, it.entities[0]);
4713+
test_uint(ecs_id(Position), ecs_field_id(&it, 1));
4714+
test_bool(false, ecs_filter_next(&it));
4715+
4716+
ecs_filter_fini(q);
4717+
4718+
ecs_fini(world);
4719+
}
4720+
4721+
void Filter_filer_iter_or_w_tag_and_component(void) {
4722+
ecs_world_t *world = ecs_mini();
4723+
4724+
ECS_COMPONENT(world, Position);
4725+
ECS_TAG(world, TagA);
4726+
4727+
ecs_filter_t *q = ecs_filter(world, {
4728+
.terms = {
4729+
{ TagA, .oper = EcsOr },
4730+
{ ecs_id(Position) }
4731+
}
4732+
});
4733+
4734+
test_assert(q != NULL);
4735+
4736+
ecs_entity_t e = ecs_new_id(world);
4737+
ecs_set(world, e, Position, {10, 20});
4738+
ecs_add(world, e, TagA);
4739+
4740+
ecs_iter_t it = ecs_filter_iter(world, q);
4741+
test_bool(true, ecs_filter_next(&it));
4742+
test_int(1, it.count);
4743+
test_uint(e, it.entities[0]);
4744+
test_uint(TagA, ecs_field_id(&it, 1));
4745+
test_bool(false, ecs_filter_next(&it));
4746+
4747+
ecs_filter_fini(q);
4748+
4749+
ecs_fini(world);
4750+
}
4751+
46904752
void Filter_filter_iter_2_or(void) {
46914753
ecs_world_t *world = ecs_mini();
46924754

test/api/src/main.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,7 +1251,9 @@ void Filter_filter_iter_2_or(void);
12511251
void Filter_filter_iter_3_or(void);
12521252
void Filter_filter_iter_2_or_other_type(void);
12531253
void Filter_filter_iter_2_or_same_type(void);
1254-
void Filter_filter_or_w_wildcard(void);
1254+
void Filter_filter_iter_or_w_wildcard(void);
1255+
void Filter_filer_iter_or_w_component_and_tag(void);
1256+
void Filter_filer_iter_or_w_tag_and_component(void);
12551257
void Filter_filter_iter_1_component(void);
12561258
void Filter_filter_iter_2_components(void);
12571259
void Filter_filter_iter_pair_id(void);
@@ -7568,8 +7570,16 @@ bake_test_case Filter_testcases[] = {
75687570
Filter_filter_iter_2_or_same_type
75697571
},
75707572
{
7571-
"filter_or_w_wildcard",
7572-
Filter_filter_or_w_wildcard
7573+
"filter_iter_or_w_wildcard",
7574+
Filter_filter_iter_or_w_wildcard
7575+
},
7576+
{
7577+
"filer_iter_or_w_component_and_tag",
7578+
Filter_filer_iter_or_w_component_and_tag
7579+
},
7580+
{
7581+
"filer_iter_or_w_tag_and_component",
7582+
Filter_filer_iter_or_w_tag_and_component
75737583
},
75747584
{
75757585
"filter_iter_1_component",
@@ -13653,7 +13663,7 @@ static bake_test_suite suites[] = {
1365313663
"Filter",
1365413664
NULL,
1365513665
NULL,
13656-
305,
13666+
307,
1365713667
Filter_testcases
1365813668
},
1365913669
{

test/meta/src/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5738,6 +5738,7 @@ bake_test_case Misc_testcases[] = {
57385738
}
57395739
};
57405740

5741+
57415742
static bake_test_suite suites[] = {
57425743
{
57435744
"PrimitiveTypes",

0 commit comments

Comments
 (0)