diff --git a/dev/implementations/table_definitions.h b/dev/implementations/table_definitions.h index c7f6177a..f68e21c9 100644 --- a/dev/implementations/table_definitions.h +++ b/dev/implementations/table_definitions.h @@ -25,10 +25,17 @@ namespace sqlite_orm { if(auto d = column.default_value()) { dft = std::move(*d); } + using constraints_tuple = decltype(column.constraints); + constexpr bool hasExplicitNull = + mpl::invoke_t>, constraints_tuple>::value; + constexpr bool hasExplicitNotNull = + mpl::invoke_t>, constraints_tuple>::value; res.emplace_back(-1, column.name, type_printer().print(), - column.is_not_null(), + !hasExplicitNull && !hasExplicitNotNull + ? column.is_not_null() + : (hasExplicitNull ? !hasExplicitNull : hasExplicitNotNull), std::move(dft), column.template is(), column.template is()); diff --git a/include/sqlite_orm/sqlite_orm.h b/include/sqlite_orm/sqlite_orm.h index ff679345..8e953841 100644 --- a/include/sqlite_orm/sqlite_orm.h +++ b/include/sqlite_orm/sqlite_orm.h @@ -23838,10 +23838,17 @@ namespace sqlite_orm { if(auto d = column.default_value()) { dft = std::move(*d); } + using constraints_tuple = decltype(column.constraints); + constexpr bool hasExplicitNull = + mpl::invoke_t>, constraints_tuple>::value; + constexpr bool hasExplicitNotNull = + mpl::invoke_t>, constraints_tuple>::value; res.emplace_back(-1, column.name, type_printer().print(), - column.is_not_null(), + !hasExplicitNull && !hasExplicitNotNull + ? column.is_not_null() + : (hasExplicitNull ? !hasExplicitNull : hasExplicitNotNull), std::move(dft), column.template is(), column.template is()); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d3ebf450..99ebafa3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -144,6 +144,7 @@ add_executable(unit_tests unique_cases/issue86.cpp unique_cases/issue937.cpp unique_cases/issue663.cpp + unique_cases/issue1357.cpp get_all_custom_containers.cpp select_constraints_tests.cpp backup_tests.cpp diff --git a/tests/unique_cases/issue1357.cpp b/tests/unique_cases/issue1357.cpp new file mode 100644 index 00000000..8934065b --- /dev/null +++ b/tests/unique_cases/issue1357.cpp @@ -0,0 +1,51 @@ +#include +#include + +#if SQLITE_VERSION_NUMBER >= 3006019 +using namespace sqlite_orm; + +#ifdef SQLITE_ORM_OPTIONAL_SUPPORTED + +TEST_CASE("issue1357") { + struct Employee { + int m_empno; + std::string m_ename; + std::string m_job; + std::optional m_mgr; + std::string m_hiredate; + double m_salary; + std::optional m_commission; + int m_depno; + }; + + struct Department { + int m_deptno; + std::string m_deptname; + std::string m_loc; + }; + + using namespace sqlite_orm; + + auto storage = make_storage("", + make_table("Emp", + make_column("empno", &Employee::m_empno, primary_key().autoincrement()), + make_column("ename", &Employee::m_ename), + make_column("job", &Employee::m_job), + make_column("mgr", &Employee::m_mgr), + make_column("hiredate", &Employee::m_hiredate), + make_column("salary", &Employee::m_salary), + make_column("comm", &Employee::m_commission), + make_column("depno", &Employee::m_depno), + foreign_key(&Employee::m_depno).references(&Department::m_deptno)), + make_table("Dept", + make_column("deptno", &Department::m_deptno, primary_key().autoincrement()), + make_column("deptname", &Department::m_deptname), + make_column("loc", &Department::m_loc, null()))); + storage.sync_schema(true); + storage.insert(Department{10, "Accounts", "New York"}); + storage.insert(Employee{1, "Paul", "Salesman", 2, "2002-02-12", 20000.0, 0.0, 1}); + storage.insert(Employee{2, "Allen", "Salesman", 2, "2002-02-12", 20000.0, 0.0, 1}); + REQUIRE_NOTHROW(storage.sync_schema(true)); +} +#endif +#endif