@@ -254,13 +254,28 @@ static int sgn(double val) noexcept
254254 return 0 ;
255255}
256256
257+ class not_null_exception : public std ::runtime_error
258+ {
259+ public:
260+ not_null_exception (std::string const &message,
261+ flex_table_column_t const *column)
262+ : std::runtime_error(message), m_column(column)
263+ {}
264+
265+ flex_table_column_t const &column () const noexcept { return *m_column; }
266+
267+ private:
268+ flex_table_column_t const *m_column;
269+ }; // class not_null_exception
270+
257271static void write_null (db_copy_mgr_t <db_deleter_by_type_and_id_t > *copy_mgr,
258272 flex_table_column_t const &column)
259273{
260274 if (column.not_null ()) {
261- throw std::runtime_error {
275+ throw not_null_exception {
262276 " Can not add NULL to column '{}' declared NOT NULL." _format (
263- column.name ())};
277+ column.name ()),
278+ &column};
264279 }
265280 copy_mgr->add_null_column ();
266281}
@@ -1572,22 +1587,33 @@ int output_flex_t::table_insert()
15721587 table_connection.new_line ();
15731588 auto *copy_mgr = table_connection.copy_mgr ();
15741589
1575- for (auto const &column : table_connection.table ()) {
1576- if (column.create_only ()) {
1577- continue ;
1578- }
1579- if (column.type () == table_column_type::id_type) {
1580- copy_mgr->add_column (type_to_char (object.type ()));
1581- } else if (column.type () == table_column_type::id_num) {
1582- copy_mgr->add_column (id);
1583- } else {
1584- write_column (copy_mgr, column);
1590+ try {
1591+ for (auto const &column : table_connection.table ()) {
1592+ if (column.create_only ()) {
1593+ continue ;
1594+ }
1595+ if (column.type () == table_column_type::id_type) {
1596+ copy_mgr->add_column (type_to_char (object.type ()));
1597+ } else if (column.type () == table_column_type::id_num) {
1598+ copy_mgr->add_column (id);
1599+ } else {
1600+ write_column (copy_mgr, column);
1601+ }
15851602 }
1603+ } catch (not_null_exception const &e) {
1604+ copy_mgr->rollback_line ();
1605+ lua_pushboolean (lua_state (), false );
1606+ lua_pushstring (lua_state (), " null value in not null column." );
1607+ lua_pushstring (lua_state (), e.column ().name ().c_str ());
1608+ push_osm_object_to_lua_stack (lua_state (), object,
1609+ get_options ()->extra_attributes );
1610+ return 4 ;
15861611 }
15871612
15881613 copy_mgr->finish_line ();
15891614
1590- return 0 ;
1615+ lua_pushboolean (lua_state (), true );
1616+ return 1 ;
15911617}
15921618
15931619int output_flex_t::table_columns ()
@@ -2184,10 +2210,17 @@ void output_flex_t::init_lua(std::string const &filename)
21842210
21852211 lua_setglobal (lua_state (), " osm2pgsql" );
21862212
2187- // Define "osmpgsql.table" metatable
2213+ // Define "osm2pgsql.table" metatable
2214+ lua_getglobal (lua_state (), " osm2pgsql" );
21882215 if (luaL_newmetatable (lua_state (), osm2pgsql_table_name) != 1 ) {
21892216 throw std::runtime_error{" Internal error: Lua newmetatable failed." };
21902217 }
2218+ lua_pushvalue (lua_state (), -1 ); // Copy of new metatable
2219+
2220+ // Add metatable as osm2pgsql.Table so we can access it from Lua
2221+ lua_setfield (lua_state (), -3 , " Table" );
2222+
2223+ // Now add functions to metatable
21912224 lua_pushvalue (lua_state (), -1 );
21922225 lua_setfield (lua_state (), -2 , " __index" );
21932226 luaX_add_table_func (lua_state (), " __tostring" ,
0 commit comments