GithubHelp home page GithubHelp logo

rbock / sqlpp17 Goto Github PK

View Code? Open in Web Editor NEW
53.0 53.0 7.0 1.09 MB

Started to re-write sqlpp11 to sqlpp17 (not even remotely ready yet)

License: BSD 2-Clause "Simplified" License

C++ 93.12% CMake 5.37% C 1.52%

sqlpp17's People

Contributors

leon0402 avatar meansquarederror avatar rbock avatar tcanabrava avatar westoleman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sqlpp17's Issues

Buld failure with gcc 13.1.1

Attempting to build sqlpp17 with gcc 13.1.1 on Linux results a failure. As far as I can see instead of choosing
sqlpp::result_t<ResultHandle>::iterator::operator!=(const T&)
it chooses
constexpr auto sqlpp::operator!=(L, R)
and the latter fails with a static assertion
Below is the full cmake output

[ 80%] Built target Catch2
[ 82%] Built target Catch2WithMain
[ 87%] Built target core_unit_tests
[ 89%] Built target sqlpp17_postgresql_serialize_parameter
[ 90%] Built target sqlpp17_postgresql_usage_insert
[ 91%] Building CXX object tests/postgresql/usage/CMakeFiles/sqlpp17_postgresql_usage_select.dir/select.cpp.o
In file included from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/clause_fwd.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/clause/from.h:30,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/clause/command.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/connection.h:32,
                 from /usr/local/projects/github/sqlpp17/tests/postgresql/usage/select.cpp:29:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/type_traits.h:376:2: warning: #warning : old code validated if nodes_of_t was emtpy. Is this really needed? [-Wcpp]
  376 | #warning : old code validated if nodes_of_t was emtpy. Is this really needed?
      |  ^~~~~~~
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/type_traits.h:404:2: warning: #warning : old code validated if nodes_of_t was emtpy. Is this really needed? [-Wcpp]
  404 | #warning : old code validated if nodes_of_t was emtpy. Is this really needed?
      |  ^~~~~~~
In file included from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/join/join.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/join/conditionless_join.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/join.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/table.h:30,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/clause/create_table.h:34,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/clause.h:29,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/connection.h:39:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/join/join_functions.h:63:2: warning: #warning : This should be checked when turning a select into a table [-Wcpp]
   63 | #warning : This should be checked when turning a select into a table
      |  ^~~~~~~
In file included from /usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:33,
                 from /usr/local/projects/github/sqlpp17/tests/postgresql/usage/select.cpp:31:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/clause/insert_into.h:91:2: warning: #warning : If something is a table, it must not have unsatisfied dependencies on other tables. It should be unnecessary to test that here. [-Wcpp]
   91 | #warning: If something is a table, it must not have unsatisfied dependencies on other tables. It should be unnecessary to test that here.
      |  ^~~~~~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:84:2: warning: #warning : Add some more tests... [-Wcpp]
   84 | #warning : Add some more tests...
      |  ^~~~~~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h: In instantiation of ‘void sqlpp::test::select_tests(Db&) [with Db = sqlpp::postgresql::base_connection<sqlpp::no_pool, sqlpp::debug::allowed>]’:
/usr/local/projects/github/sqlpp17/tests/postgresql/usage/select.cpp:42:32:   required from here
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:57:5: error: inconsistent begin/end types in range-based ‘for’ statement: ‘sqlpp::result_t<sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, sqlpp::column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true> > > >::iterator’ and ‘sqlpp::result_end_t’
   57 |     for (const auto& row : db(sqlpp::select(::test::tabDepartment.id, ::test::tabDepartment.name)
      |     ^~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:57:5: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
In file included from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/operator.h:50,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/core/column.h:31,
                 from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/clause/create_table.h:32:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/operator/not_equal_to.h:39:18: note: candidate 1: ‘constexpr auto sqlpp::operator!=(L, R) [with L = result_t<postgresql::char_result_t<result_row_t<column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true> > > >::iterator; R = result_end_t]’
   39 |   constexpr auto operator!=(L l, R r)
      |                  ^~~~~~~~
In file included from /usr/local/projects/github/sqlpp17/include/sqlpp17/postgresql/connection.h:34:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/result.h:95:12: note: candidate 2: ‘bool sqlpp::result_t<ResultHandle>::iterator::operator!=(const T&) const [with T = sqlpp::result_end_t; ResultHandle = sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, sqlpp::column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true> > >]’
   95 |       auto operator!=(const T& rhs) const -> bool
      |            ^~~~~~~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:57:5: error: could not convert ‘sqlpp::operator!=<result_t<postgresql::char_result_t<result_row_t<column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true> > > >::iterator, result_end_t>(__for_begin , (__for_end , sqlpp::result_end_t()))’ from ‘sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >’ to ‘bool’
   57 |     for (const auto& row : db(sqlpp::select(::test::tabDepartment.id, ::test::tabDepartment.name)
      |     ^~~
      |     |
      |     sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:64:5: error: inconsistent begin/end types in range-based ‘for’ statement: ‘sqlpp::result_t<sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, sqlpp::column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true>, sqlpp::column_spec<test::TabDepartment::Division::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, false> > > >::iterator’ and ‘sqlpp::result_end_t’
   64 |     for (const auto& row :
      |     ^~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:64:5: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/operator/not_equal_to.h:39:18: note: candidate 1: ‘constexpr auto sqlpp::operator!=(L, R) [with L = result_t<postgresql::char_result_t<result_row_t<column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true>, column_spec<test::TabDepartment::Division::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, false> > > >::iterator; R = result_end_t]’
   39 |   constexpr auto operator!=(L l, R r)
      |                  ^~~~~~~~
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/result.h:95:12: note: candidate 2: ‘bool sqlpp::result_t<ResultHandle>::iterator::operator!=(const T&) const [with T = sqlpp::result_end_t; ResultHandle = sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, sqlpp::column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true>, sqlpp::column_spec<test::TabDepartment::Division::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, false> > >]’
   95 |       auto operator!=(const T& rhs) const -> bool
      |            ^~~~~~~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:64:5: error: could not convert ‘sqlpp::operator!=<result_t<postgresql::char_result_t<result_row_t<column_spec<test::TabDepartment::Id::_sqlpp_name_tag, long int, false>, column_spec<test::TabDepartment::Name::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, true>, column_spec<test::TabDepartment::Division::_sqlpp_name_tag, std::basic_string_view<char, std::char_traits<char> >, false> > > >::iterator, result_end_t>(__for_begin , (__for_end , sqlpp::result_end_t()))’ from ‘sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >’ to ‘bool’
   64 |     for (const auto& row :
      |     ^~~
      |     |
      |     sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:70:5: error: inconsistent begin/end types in range-based ‘for’ statement: ‘sqlpp::result_t<sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_rowCount, long int, false>, sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_maxName, std::basic_string_view<char, std::char_traits<char> >, false>, sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_avgId, double, false>, sqlpp::column_spec<test::TabPerson::IsManager::_sqlpp_name_tag, bool, false> > > >::iterator’ and ‘sqlpp::result_end_t’
   70 |     for (const auto& row : db(select(::sqlpp::count(1).as(rowCount), max(::test::tabPerson.name).as(maxName),
      |     ^~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:70:5: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/operator/not_equal_to.h:39:18: note: candidate 1: ‘constexpr auto sqlpp::operator!=(L, R) [with L = result_t<postgresql::char_result_t<result_row_t<column_spec<test::sqlpp_name_tag_for_rowCount, long int, false>, column_spec<test::sqlpp_name_tag_for_maxName, std::basic_string_view<char, std::char_traits<char> >, false>, column_spec<test::sqlpp_name_tag_for_avgId, double, false>, column_spec<test::TabPerson::IsManager::_sqlpp_name_tag, bool, false> > > >::iterator; R = result_end_t]’
   39 |   constexpr auto operator!=(L l, R r)
      |                  ^~~~~~~~
/usr/local/projects/github/sqlpp17/include/sqlpp17/core/result.h:95:12: note: candidate 2: ‘bool sqlpp::result_t<ResultHandle>::iterator::operator!=(const T&) const [with T = sqlpp::result_end_t; ResultHandle = sqlpp::postgresql::char_result_t<sqlpp::result_row_t<sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_rowCount, long int, false>, sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_maxName, std::basic_string_view<char, std::char_traits<char> >, false>, sqlpp::column_spec<sqlpp::test::sqlpp_name_tag_for_avgId, double, false>, sqlpp::column_spec<test::TabPerson::IsManager::_sqlpp_name_tag, bool, false> > >]’
   95 |       auto operator!=(const T& rhs) const -> bool
      |            ^~~~~~~~
/usr/local/projects/github/sqlpp17/tests/include/core_test/select_tests.h:70:5: error: could not convert ‘sqlpp::operator!=<result_t<postgresql::char_result_t<result_row_t<column_spec<test::sqlpp_name_tag_for_rowCount, long int, false>, column_spec<test::sqlpp_name_tag_for_maxName, std::basic_string_view<char, std::char_traits<char> >, false>, column_spec<test::sqlpp_name_tag_for_avgId, double, false>, column_spec<test::TabPerson::IsManager::_sqlpp_name_tag, bool, false> > > >::iterator, result_end_t>(__for_begin , (__for_end , sqlpp::result_end_t()))’ from ‘sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >’ to ‘bool’
   70 |     for (const auto& row : db(select(::sqlpp::count(1).as(rowCount), max(::test::tabPerson.name).as(maxName),
      |     ^~~
      |     |
      |     sqlpp::bad_expression_t<sqlpp::failed<sqlpp::assert_comparison_operands_are_compatible> >
gmake[2]: *** [tests/postgresql/usage/CMakeFiles/sqlpp17_postgresql_usage_select.dir/build.make:76: tests/postgresql/usage/CMakeFiles/sqlpp17_postgresql_usage_select.dir/select.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:1178: tests/postgresql/usage/CMakeFiles/sqlpp17_postgresql_usage_select.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2

order of evaluation problem

Hi,

I found there are some code like:

struct
{
  bool first = true;
  [[nodiscard]] auto to_string() -> std::string
  {
    if (first)
    {
      first = false;
      return "";
    }
    else
    {
      return ", ";
    }
  }
} separator;

return (std ::string{} + ... + (separator.to_string() + to_sql_column_spec_string(context, ColumnSpecs{})));

template <typename TableSpec, typename... ColumnSpecs>

Such code might be undefined behavior due to the order of evaluation

By the standard, the first separator("") could be introduced to any place between the columns.
For gcc, the empty separator is place to the back of the line.

Here is a demo of such bug on ideone.

Thanks,

Type Trait Categories

I was wondering if we might need a clear definition and documentation of our type traits / error messages. I think it's somewhat difficult to understand in the code & error message what an expression is exactly for instance.

There are two things I don't like currently in the code that I tested:

  • is_expression_v is somewhat restrictive resulting in lines like not is_expression_v<Expression> and not std::is_integral_v<Expression> and not is_text_v<Expression>, where you explicitly allow some things again
  • The relation between is_expression_v and some other traits is unclear like has_ordable_value_v or has_numeric_value_v

My suggestion would be:

  • is_expression_v should be more general and include all valid sql: Columns, Subqueries, Alias, sqlpp:star, all kinds of literals values, ...
  • There should be type traits which are more restrictive and direct subsets of expressions like is_numeric_expression_v and is_aggregate_expression_v

The consequences would be:

  • More checks needed to rule out for instance sqlpp:star in many commands, but more specific and helpful error message -> "max(*) is not allowed"
  • "Everything is allowed by default" approach. The chance is increased that we forget some of the checks and thus allow invalid sql syntax. But we decrease the chance that we disallow valid sql syntax. This is better in my opinion.
  • Code is easier to understand
    • No "and chaining". Like in count.h, where we currently disallow every non expression except numerical literals and text literals. This also leads to confusing error messages "arg must be an expression or a numeric literal or a text literal or ... " instead of more helpful messages like "arg cannot be ..."
    • Relations between traits a very clear based on the naming. Currently I always wonder in say max.h if has_ordable_value_v really checks everything needed

What do you think? Would this work out for the complete code (my suggestions are mainly based on what I have tested so far)?

Edit: Regarding the issue that there might be too many extra checks (like checking in most cases that sqlpp:star is disallowed), we would always have the option to add more "convenience type traits" that are more specific than is_expression_v say is_value_expression. These aren't self explaining, so they would need to be documented well (tradeoff). A better solution might be investigating how we can share code, which does the same checks, but throw different asserts (or assert messages).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.