rbock / sqlpp17 Goto Github PK
View Code? Open in Web Editor NEWStarted to re-write sqlpp11 to sqlpp17 (not even remotely ready yet)
License: BSD 2-Clause "Simplified" License
Started to re-write sqlpp11 to sqlpp17 (not even remotely ready yet)
License: BSD 2-Clause "Simplified" License
C++ 20 is coming soon. Is there any plan for this project?
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
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{})));
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,
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 againis_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, ...is_numeric_expression_v
and is_aggregate_expression_v
The consequences would be:
sqlpp:star
in many commands, but more specific and helpful error message -> "max(*) is not allowed"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 ..."max.h
if has_ordable_value_v
really checks everything neededWhat 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).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.