Skip to content

Commit 707af52

Browse files
authored
Merge pull request #1746 from joto/geom-several-columns
Make the check trigger work with multiple geom columns
2 parents 152bafc + 5e661d6 commit 707af52

File tree

5 files changed

+43
-23
lines changed

5 files changed

+43
-23
lines changed

src/flex-table.cpp

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,14 @@ flex_table_column_t &flex_table_t::add_column(std::string const &name,
7373
(m_columns.size() == 1 &&
7474
m_columns[0].type() == table_column_type::id_type));
7575

76-
m_columns.emplace_back(name, type, sql_type);
77-
auto &column = m_columns.back();
76+
auto &column = m_columns.emplace_back(name, type, sql_type);
7877

7978
if (column.is_geometry_column()) {
80-
if (m_geom_column != std::numeric_limits<std::size_t>::max()) {
79+
if (m_geom_column == std::numeric_limits<std::size_t>::max()) {
80+
m_geom_column = m_columns.size() - 1;
81+
} else {
8182
m_has_multiple_geom_columns = true;
8283
}
83-
m_geom_column = m_columns.size() - 1;
84-
column.set_not_null();
8584
}
8685

8786
return column;
@@ -162,6 +161,30 @@ void table_connection_t::connect(std::string const &conninfo)
162161
m_db_connection->exec("SET synchronous_commit = off");
163162
}
164163

164+
static void
165+
enable_check_trigger(pg_conn_t *db_connection, flex_table_t const &table)
166+
{
167+
std::string checks;
168+
169+
for (auto const &column : table) {
170+
if (column.is_geometry_column() && column.needs_isvalid()) {
171+
checks.append(
172+
R"((NEW."{0}" IS NULL OR ST_IsValid(NEW."{0}")) AND )"_format(
173+
column.name()));
174+
}
175+
}
176+
177+
if (checks.empty()) {
178+
return;
179+
}
180+
181+
// remove last " AND "
182+
checks.resize(checks.size() - 5);
183+
184+
create_geom_check_trigger(db_connection, table.schema(), table.name(),
185+
checks);
186+
}
187+
165188
void table_connection_t::start(bool append)
166189
{
167190
assert(m_db_connection);
@@ -184,12 +207,7 @@ void table_connection_t::start(bool append)
184207
: flex_table_t::table_type::permanent,
185208
table().full_name()));
186209

187-
if (table().has_geom_column() &&
188-
table().geom_column().needs_isvalid()) {
189-
create_geom_check_trigger(m_db_connection.get(), table().schema(),
190-
table().name(),
191-
table().geom_column().name());
192-
}
210+
enable_check_trigger(m_db_connection.get(), table());
193211
}
194212

195213
prepare();
@@ -254,10 +272,8 @@ void table_connection_t::stop(bool updateable, bool append)
254272
table().full_tmp_name(), table().name()));
255273
m_id_index_created = false;
256274

257-
if (updateable && table().geom_column().needs_isvalid()) {
258-
create_geom_check_trigger(m_db_connection.get(), table().schema(),
259-
table().name(),
260-
table().geom_column().name());
275+
if (updateable) {
276+
enable_check_trigger(m_db_connection.get(), table());
261277
}
262278
}
263279

src/flex-table.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class flex_table_t
110110
return m_geom_column != std::numeric_limits<std::size_t>::max();
111111
}
112112

113-
// XXX should we allow several geometry columns?
113+
/// Get the (first, if there are multiple) geometry column.
114114
flex_table_column_t const &geom_column() const noexcept
115115
{
116116
assert(has_geom_column());
@@ -218,7 +218,10 @@ class flex_table_t
218218
*/
219219
std::vector<flex_table_column_t> m_columns;
220220

221-
/// Index of the geometry column in m_columns. Default means no geometry.
221+
/**
222+
* Index of the (first) geometry column in m_columns. Default means no
223+
* geometry column.
224+
*/
222225
std::size_t m_geom_column = std::numeric_limits<std::size_t>::max();
223226

224227
/**

src/pgsql-helper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,20 @@ idlist_t get_ids_from_db(pg_conn_t const *db_connection, char const *stmt,
3535
void create_geom_check_trigger(pg_conn_t *db_connection,
3636
std::string const &schema,
3737
std::string const &table,
38-
std::string const &geom_column)
38+
std::string const &condition)
3939
{
4040
std::string func_name = qualified_name(schema, table + "_osm2pgsql_valid");
4141

4242
db_connection->exec(
4343
"CREATE OR REPLACE FUNCTION {}()\n"
4444
"RETURNS TRIGGER AS $$\n"
4545
"BEGIN\n"
46-
" IF ST_IsValid(NEW.{}) THEN \n"
46+
" IF {} THEN \n"
4747
" RETURN NEW;\n"
4848
" END IF;\n"
4949
" RETURN NULL;\n"
5050
"END;"
51-
"$$ LANGUAGE plpgsql;"_format(func_name, geom_column));
51+
"$$ LANGUAGE plpgsql;"_format(func_name, condition));
5252

5353
db_connection->exec(
5454
"CREATE TRIGGER \"{}\""

src/pgsql-helper.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ idlist_t get_ids_from_db(pg_conn_t const *db_connection, char const *stmt,
3333
void create_geom_check_trigger(pg_conn_t *db_connection,
3434
std::string const &schema,
3535
std::string const &table,
36-
std::string const &geom_column);
36+
std::string const &condition);
3737

3838
void drop_geom_check_trigger(pg_conn_t *db_connection,
3939
std::string const &schema,

src/table.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void table_t::start(std::string const &conninfo, std::string const &table_space)
134134

135135
if (m_srid != "4326") {
136136
create_geom_check_trigger(m_sql_conn.get(), m_target->schema,
137-
m_target->name, "way");
137+
m_target->name, "ST_IsValid(NEW.way)");
138138
}
139139
}
140140

@@ -243,7 +243,8 @@ void table_t::stop(bool updateable, bool enable_hstore_index,
243243
qual_name, tablespace_clause(table_space_index)));
244244
if (m_srid != "4326") {
245245
create_geom_check_trigger(m_sql_conn.get(), m_target->schema,
246-
m_target->name, "way");
246+
m_target->name,
247+
"ST_IsValid(NEW.way)");
247248
}
248249
}
249250

0 commit comments

Comments
 (0)