Skip to content

Commit 264c958

Browse files
committed
Add not_null and create_only options to table columns definitions
1 parent 948377c commit 264c958

8 files changed

Lines changed: 71 additions & 26 deletions

File tree

docs/flex.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ Instead of the above types you can use any SQL type you want. If you do that
115115
you have to supply the PostgreSQL string representation for that type when
116116
adding data to such columns (or Lua nil to set the column to `NULL`).
117117

118+
When defining a column you can add the following options:
119+
* `not_null = true`: Make this a `NOT NULL` column.
120+
* `create_only = true`: Add the column to the `CREATE TABLE` command, but
121+
do not try to fill this column when adding data. This can be useful for
122+
`SERIAL` columns or when you want to fill in the column later yourself.
123+
118124
### Processing callbacks
119125

120126
You are expected to define one or more of the following functions:

flex-config/data-types.lua

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55

66
local highways = osm2pgsql.define_way_table('highways', {
77
{ column = 'name', type = 'text' },
8-
{ column = 'type', type = 'text' },
8+
-- We always need a highway type, so we can declare the column as NOT NULL
9+
{ column = 'type', type = 'text', not_null = true },
10+
11+
-- Add a SERIAL column and tell osm2pgsql not to fill it (PostgreSQL will
12+
-- do that for us)
13+
{ column = 'id', type = 'serial', create_only = true },
914

1015
-- type "direction" is special, see below
1116
{ column = 'oneway', type = 'direction' },

src/flex-table-column.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ std::string flex_table_column_t::sql_modifiers() const
143143
{
144144
std::string modifiers;
145145

146-
if ((m_flags & table_column_flags::not_null) != 0U) {
146+
if (m_not_null) {
147147
modifiers += "NOT NULL ";
148148
}
149149

src/flex-table-column.hpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ enum class table_column_type : uint8_t
3838
id_num
3939
};
4040

41-
enum table_column_flags : uint8_t
42-
{
43-
none = 0,
44-
not_null = 1
45-
};
46-
4741
/**
4842
* A column in a flex_table_t.
4943
*/
@@ -56,8 +50,6 @@ class flex_table_column_t
5650

5751
table_column_type type() const noexcept { return m_type; }
5852

59-
table_column_flags flags() const noexcept { return m_flags; }
60-
6153
bool is_point_column() const noexcept
6254
{
6355
return (m_type == table_column_type::point) ||
@@ -85,11 +77,13 @@ class flex_table_column_t
8577

8678
std::string const &type_name() const noexcept { return m_type_name; }
8779

88-
void set_not_null_constraint() noexcept
89-
{
90-
m_flags = static_cast<table_column_flags>(m_flags |
91-
table_column_flags::not_null);
92-
}
80+
bool not_null() const noexcept { return m_not_null; }
81+
82+
bool create_only() const noexcept { return m_create_only; }
83+
84+
void set_not_null(bool value = true) noexcept { m_not_null = value; }
85+
86+
void set_create_only(bool value = true) noexcept { m_create_only = value; }
9387

9488
std::string sql_type_name(int srid) const;
9589
std::string sql_modifiers() const;
@@ -111,8 +105,11 @@ class flex_table_column_t
111105
*/
112106
table_column_type m_type;
113107

114-
/// Flags like NOT NULL.
115-
table_column_flags m_flags = table_column_flags::none;
108+
/// NOT NULL constraint
109+
bool m_not_null = false;
110+
111+
/// Column will be created but not filled by osm2pgsql.
112+
bool m_create_only = false;
116113
};
117114

118115
#endif // OSM2PGSQL_FLEX_TABLE_COLUMN_HPP

src/flex-table.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ flex_table_column_t &flex_table_t::add_column(std::string const &name,
7575

7676
if (column.is_geometry_column()) {
7777
m_geom_column = m_columns.size() - 1;
78-
column.set_not_null_constraint();
78+
column.set_not_null();
7979
}
8080

8181
return column;
@@ -127,10 +127,12 @@ std::string flex_table_t::build_sql_column_list() const
127127

128128
std::string result;
129129
for (auto const &column : m_columns) {
130-
result += '"';
131-
result += column.name();
132-
result += '"';
133-
result += ',';
130+
if (!column.create_only()) {
131+
result += '"';
132+
result += column.name();
133+
result += '"';
134+
result += ',';
135+
}
134136
}
135137
result.resize(result.size() - 1);
136138

src/lua-utils.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,24 @@ char const *luaX_get_table_string(lua_State *lua_state, char const *key,
114114
}
115115
return lua_tostring(lua_state, -1);
116116
}
117+
118+
bool luaX_get_table_bool(lua_State *lua_state, char const *key, int table_index,
119+
char const *error_msg, bool default_value)
120+
{
121+
assert(lua_state);
122+
assert(key);
123+
assert(error_msg);
124+
lua_getfield(lua_state, table_index, key);
125+
auto const type = lua_type(lua_state, -1);
126+
127+
if (type == LUA_TNIL) {
128+
return default_value;
129+
}
130+
131+
if (type == LUA_TBOOLEAN) {
132+
return lua_toboolean(lua_state, -1);
133+
}
134+
135+
throw std::runtime_error{
136+
"{} must contain a '{}' boolean field"_format(error_msg, key)};
137+
}

src/lua-utils.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,7 @@ void luaX_add_table_array(lua_State *lua_state, char const *key,
4646
char const *luaX_get_table_string(lua_State *lua_state, char const *key,
4747
int table_index, char const *error_msg);
4848

49+
bool luaX_get_table_bool(lua_State *lua_state, char const *key, int table_index,
50+
char const *error_msg, bool default_value);
51+
4952
#endif // OSM2PGSQL_FLEX_LUA_HPP

src/output-flex.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,9 @@ void output_flex_t::write_row(flex_table_t *table, osmium::item_type id_type,
326326
auto *copy_mgr = table->copy_mgr();
327327

328328
for (auto const &column : *table) {
329+
if (column.create_only()) {
330+
continue;
331+
}
329332
if (column.type() == table_column_type::id_type) {
330333
copy_mgr->add_column(type_to_char(id_type));
331334
} else if (column.type() == table_column_type::id_num) {
@@ -509,7 +512,7 @@ void output_flex_t::setup_id_columns(flex_table_t *table)
509512
}
510513
lua_pop(lua_state(), 1); // type_column
511514
auto &column = table->add_column(type_column_name, "id_type");
512-
column.set_not_null_constraint();
515+
column.set_not_null();
513516
table->set_id_type(osmium::item_type::undefined);
514517
} else {
515518
throw std::runtime_error{"Unknown ids type: " + type};
@@ -520,7 +523,7 @@ void output_flex_t::setup_id_columns(flex_table_t *table)
520523
check_name(name, "column");
521524

522525
auto &column = table->add_column(name, "id_num");
523-
column.set_not_null_constraint();
526+
column.set_not_null();
524527
lua_pop(lua_state(), 3); // id_column, type, ids
525528
}
526529

@@ -551,9 +554,15 @@ void output_flex_t::setup_flex_table_columns(flex_table_t *table)
551554
luaX_get_table_string(lua_state(), "column", -2, "Column entry");
552555
check_name(name, "column");
553556

554-
table->add_column(name, type);
557+
auto &column = table->add_column(name, type);
558+
559+
column.set_not_null(luaX_get_table_bool(lua_state(), "not_null", -3,
560+
"Entry 'not_null'", false));
561+
562+
column.set_create_only(luaX_get_table_bool(
563+
lua_state(), "create_only", -4, "Entry 'create_only'", false));
555564

556-
lua_pop(lua_state(), 3); // column, type, table
565+
lua_pop(lua_state(), 5); // create_only, not_null, column, type, table
557566
++num_columns;
558567
}
559568

@@ -670,6 +679,8 @@ int output_flex_t::table_columns()
670679
column.sql_type_name(table.srid()).c_str());
671680
luaX_add_table_str(lua_state(), "sql_modifiers",
672681
column.sql_modifiers().c_str());
682+
luaX_add_table_bool(lua_state(), "not_null", column.not_null());
683+
luaX_add_table_bool(lua_state(), "create_only", column.create_only());
673684

674685
lua_rawset(lua_state(), -3);
675686
}

0 commit comments

Comments
 (0)