From c729387ab66b19acdff02f047660bdda8f75b343 Mon Sep 17 00:00:00 2001 From: rbock Date: Thu, 11 Apr 2019 11:30:25 +0200 Subject: [PATCH] Allow INSERT INTO from SELECT --- include/sqlpp11/insert_value_list.h | 26 +++++++++++++++----------- test_serializer/CustomQuery.cpp | 20 ++++++++++++++++---- tests/Insert.cpp | 6 ++++-- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/include/sqlpp11/insert_value_list.h b/include/sqlpp11/insert_value_list.h index 10fe19e6..56c36104 100644 --- a/include/sqlpp11/insert_value_list.h +++ b/include/sqlpp11/insert_value_list.h @@ -627,17 +627,17 @@ namespace sqlpp context << " ("; interpret_tuple(t._columns, ",", context); context << ")"; - context << " VALUES "; bool first = true; for (const auto& row : t._insert_values) { - if (not first) + if (first) { - context << ','; + context << " VALUES "; + first = false; } else { - first = false; + context << ','; } context << '('; interpret_tuple(row, ",", context); @@ -669,14 +669,18 @@ namespace sqlpp context << ','; } interpret_list(t._dynamic_columns, ',', context); - context << ") VALUES("; - interpret_tuple(t._values, ",", context); - if (sizeof...(Assignments) and not t._dynamic_values.empty()) - { - context << ','; - } - interpret_list(t._dynamic_values, ',', context); context << ")"; + if (sizeof...(Assignments) or not t._dynamic_values.empty()) + { + context << " VALUES("; + interpret_tuple(t._values, ",", context); + if (sizeof...(Assignments) and not t._dynamic_values.empty()) + { + context << ','; + } + interpret_list(t._dynamic_values, ',', context); + context << ")"; + } } return context; } diff --git a/test_serializer/CustomQuery.cpp b/test_serializer/CustomQuery.cpp index 4c00aec5..f86a859d 100644 --- a/test_serializer/CustomQuery.cpp +++ b/test_serializer/CustomQuery.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2016, Roland Bock + * Copyright (c) 2016-2019, Roland Bock * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -31,15 +31,16 @@ SQLPP_ALIAS_PROVIDER(pragma) -int CustomQuery(int, char* []) +int CustomQuery(int, char*[]) { const auto foo = test::TabFoo{}; const auto bar = test::TabBar{}; auto db = MockDb{}; // Unconditionally - compare(__LINE__, custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega), from(foo), - sqlpp::unconditionally()), + compare(__LINE__, + custom_query(sqlpp::select(), select_flags(sqlpp::distinct), select_columns(foo.omega), from(foo), + sqlpp::unconditionally()), "SELECT DISTINCT tab_foo.omega FROM tab_foo "); // A full select statement made individual clauses @@ -68,5 +69,16 @@ int CustomQuery(int, char* []) custom_query(sqlpp::verbatim("PRAGMA user_version")).with_result_type_of(select(sqlpp::value(1).as(pragma))), " PRAGMA user_version"); + // An insert from select for postgresql + const auto x = 17; + compare(__LINE__, + custom_query(insert_into(foo).columns(foo.omega), + select(sqlpp::value(x).as(foo.omega)) + .from(foo) + .where(not exists(select(foo.omega).from(foo).where(foo.omega == x)))), + "INSERT INTO tab_foo (omega) " + "SELECT 17 AS omega FROM tab_foo " + "WHERE (NOT EXISTS(SELECT tab_foo.omega FROM tab_foo WHERE (tab_foo.omega=17)))"); + return 0; } diff --git a/tests/Insert.cpp b/tests/Insert.cpp index a364fdce..34e3a48c 100644 --- a/tests/Insert.cpp +++ b/tests/Insert.cpp @@ -66,9 +66,11 @@ int Insert(int, char*[]) multi_insert.values.add(t.gamma = true, t.beta = "cheesecake", t.delta = 1); multi_insert.values.add(t.gamma = sqlpp::default_value, t.beta = sqlpp::default_value, t.delta = sqlpp::default_value); - multi_insert.values.add(t.gamma = sqlpp::value_or_null(true), - t.beta = sqlpp::value_or_null("pie"), + multi_insert.values.add(t.gamma = sqlpp::value_or_null(true), t.beta = sqlpp::value_or_null("pie"), t.delta = sqlpp::value_or_null(sqlpp::null)); + printer.reset(); + std::cerr << serialize(multi_insert, printer).str() << std::endl; + auto i = dynamic_insert_into(db, t).dynamic_set(); i.insert_list.add(t.beta = "kirschauflauf"); printer.reset();