Skip to content

Commit a08254f

Browse files
committed
Fix node->relation dependency tracking and test node dependency tracking
Fixes #1048
1 parent 22037d4 commit a08254f

File tree

2 files changed

+109
-5
lines changed

2 files changed

+109
-5
lines changed

src/middle-pgsql.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,8 +756,9 @@ static table_sql sql_for_relations() noexcept
756756
" AND parts[way_off+1:rel_off] && ARRAY[$1];\n";
757757

758758
sql.prepare_mark = "PREPARE mark_rels_by_node(int8) AS"
759-
" SELECT id FROM {prefix}_ways"
760-
" WHERE nodes && ARRAY[$1];\n"
759+
" SELECT id FROM {prefix}_rels"
760+
" WHERE parts && ARRAY[$1]"
761+
" AND parts[1:way_off] && ARRAY[$1];\n"
761762
"PREPARE mark_rels_by_way(int8) AS"
762763
" SELECT id FROM {prefix}_rels"
763764
" WHERE parts && ARRAY[$1]"

tests/test-middle.cpp

Lines changed: 106 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,19 +1011,33 @@ class test_pending_processor : public middle_t::pending_processor
10111011
test_pending_processor() = default;
10121012

10131013
void enqueue_ways(osmid_t id) override { m_way_ids.push_back(id); }
1014+
void enqueue_relations(osmid_t id) override { m_rel_ids.push_back(id); }
10141015

10151016
void process_ways() override {}
1016-
void enqueue_relations(osmid_t) override {}
10171017
void process_relations() override {}
10181018

10191019
void check_way_ids_equal_to(std::initializer_list<osmid_t> list) noexcept
10201020
{
1021-
REQUIRE(m_way_ids.size() == list.size());
1022-
REQUIRE(std::equal(m_way_ids.cbegin(), m_way_ids.cend(), list.begin()));
1021+
REQUIRE(compare(m_way_ids, list));
1022+
}
1023+
1024+
void check_rel_ids_equal_to(std::initializer_list<osmid_t> list) noexcept
1025+
{
1026+
REQUIRE(compare(m_rel_ids, list));
10231027
}
10241028

10251029
private:
1030+
static bool compare(std::vector<osmid_t> const &l1,
1031+
std::initializer_list<osmid_t> const &l2) noexcept
1032+
{
1033+
if (l1.size() != l2.size()) {
1034+
return false;
1035+
}
1036+
return std::equal(l1.cbegin(), l1.cend(), l2.begin());
1037+
}
1038+
10261039
std::vector<osmid_t> m_way_ids;
1040+
std::vector<osmid_t> m_rel_ids;
10271041
};
10281042

10291043
TEMPLATE_TEST_CASE("middle: change nodes in way", "", options_slim_default,
@@ -1171,3 +1185,92 @@ TEMPLATE_TEST_CASE("middle: change nodes in way", "", options_slim_default,
11711185
}
11721186
}
11731187
}
1188+
1189+
TEMPLATE_TEST_CASE("middle: change nodes in relation", "", options_slim_default,
1190+
options_slim_dense_cache, options_flat_node_cache)
1191+
{
1192+
options_t options = TestType::options(db);
1193+
1194+
testing::cleanup::file_t flatnode_cleaner{
1195+
options.flat_node_file.get_value_or("")};
1196+
1197+
// create some nodes, ways, and relations we'll use for the tests
1198+
test_buffer_t buffer;
1199+
auto const &node10 = buffer.add_node_and_get(10, 1.0, 0.0);
1200+
auto const &node11 = buffer.add_node_and_get(11, 1.1, 0.0);
1201+
auto const &node12 = buffer.add_node_and_get(12, 1.2, 0.0);
1202+
auto const &node10a = buffer.add_node_and_get(10, 1.0, 1.0);
1203+
auto const &node11a = buffer.add_node_and_get(11, 1.1, 1.0);
1204+
1205+
auto const &way20 = buffer.add_way_and_get(20, {11, 12});
1206+
1207+
using otype = osmium::item_type;
1208+
auto const &rel30 = buffer.add_relation_and_get(30, {{otype::node, 10}});
1209+
auto const &rel31 = buffer.add_relation_and_get(31, {{otype::way, 20}});
1210+
1211+
// Set up middle in "create" mode to get a cleanly initialized database and
1212+
// add some nodes and ways. Does this in its own scope so that the mid is
1213+
// closed properly.
1214+
{
1215+
auto mid = std::make_shared<middle_pgsql_t>(&options);
1216+
mid->start();
1217+
1218+
mid->node_set(node10);
1219+
mid->node_set(node11);
1220+
mid->node_set(node12);
1221+
mid->flush();
1222+
mid->way_set(way20);
1223+
mid->flush();
1224+
mid->relation_set(rel30);
1225+
mid->relation_set(rel31);
1226+
mid->flush();
1227+
1228+
// Nothing pending yet
1229+
REQUIRE_FALSE(mid->has_pending());
1230+
1231+
mid->commit();
1232+
}
1233+
1234+
// From now on use append mode to not destroy the data we just added.
1235+
options.append = true;
1236+
1237+
SECTION("Single relation directly affected")
1238+
{
1239+
auto mid = std::make_shared<middle_pgsql_t>(&options);
1240+
mid->start();
1241+
1242+
mid->node_delete(10);
1243+
mid->node_set(node10a);
1244+
mid->node_changed(10);
1245+
mid->flush();
1246+
1247+
REQUIRE(mid->has_pending());
1248+
test_pending_processor proc;
1249+
mid->iterate_relations(proc);
1250+
1251+
proc.check_rel_ids_equal_to({30});
1252+
check_relation(mid, rel30);
1253+
1254+
mid->commit();
1255+
}
1256+
1257+
SECTION("Single relation indirectly affected (through way)")
1258+
{
1259+
auto mid = std::make_shared<middle_pgsql_t>(&options);
1260+
mid->start();
1261+
1262+
mid->node_delete(11);
1263+
mid->node_set(node11a);
1264+
mid->node_changed(11);
1265+
mid->flush();
1266+
1267+
REQUIRE(mid->has_pending());
1268+
test_pending_processor proc;
1269+
mid->iterate_ways(proc);
1270+
proc.check_way_ids_equal_to({20});
1271+
1272+
mid->iterate_relations(proc);
1273+
proc.check_rel_ids_equal_to({31});
1274+
check_relation(mid, rel31);
1275+
}
1276+
}

0 commit comments

Comments
 (0)