aboutsummaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-06-21 12:52:18 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-06-29 13:11:59 +0200
commita87c149915fa5a262bd797df1c2a4e756420d413 (patch)
tree620bfe6a33af12e84030139a8fa53d8ecf0de669 /odb/relational
parent371ec576553528fc7b8532bf00673cb222836349 (diff)
Add support for bulk operations in PostgreSQL 14
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/pgsql/context.cxx2
-rw-r--r--odb/relational/pgsql/header.cxx14
-rw-r--r--odb/relational/pgsql/source.cxx6
-rw-r--r--odb/relational/source.cxx59
4 files changed, 62 insertions, 19 deletions
diff --git a/odb/relational/pgsql/context.cxx b/odb/relational/pgsql/context.cxx
index a9f34dd..7f99f5d 100644
--- a/odb/relational/pgsql/context.cxx
+++ b/odb/relational/pgsql/context.cxx
@@ -85,7 +85,7 @@ namespace relational
insert_send_auto_id = false;
delay_freeing_statement_result = false;
need_image_clone = false;
- generate_bulk = false;
+ generate_bulk = true;
global_index = true;
global_fkey = false;
data_->bind_vector_ = "pgsql::bind*";
diff --git a/odb/relational/pgsql/header.cxx b/odb/relational/pgsql/header.cxx
index ff00eaa..c3efc3e 100644
--- a/odb/relational/pgsql/header.cxx
+++ b/odb/relational/pgsql/header.cxx
@@ -87,6 +87,20 @@ namespace relational
}
os << endl;
+
+ if (poly_derived)
+ return;
+
+ // Bulk operations batch size.
+ //
+ {
+ unsigned long long b (c.count ("bulk")
+ ? c.get<unsigned long long> ("bulk")
+ : 1);
+
+ os << "static const std::size_t batch = " << b << "UL;"
+ << endl;
+ }
}
virtual void
diff --git a/odb/relational/pgsql/source.cxx b/odb/relational/pgsql/source.cxx
index 580103d..b881e48 100644
--- a/odb/relational/pgsql/source.cxx
+++ b/odb/relational/pgsql/source.cxx
@@ -203,7 +203,7 @@ namespace relational
traverse_numeric (member_info& mi)
{
os << b << ".type = pgsql::bind::numeric;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data_ptr ();"
<< b << ".capacity = " << arg << "." << mi.var <<
"value.capacity ();"
<< b << ".size = &" << arg << "." << mi.var << "size;"
@@ -224,7 +224,7 @@ namespace relational
{
os << b << ".type = " <<
char_bin_buffer_types[mi.st->type - sql_type::CHAR] << ";"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data_ptr ();"
<< b << ".capacity = " << arg << "." << mi.var <<
"value.capacity ();"
<< b << ".size = &" << arg << "." << mi.var << "size;"
@@ -245,7 +245,7 @@ namespace relational
traverse_varbit (member_info& mi)
{
os << b << ".type = pgsql::bind::varbit;"
- << b << ".buffer = " << arg << "." << mi.var << "value.data ();"
+ << b << ".buffer = " << arg << "." << mi.var << "value.data_ptr ();"
<< b << ".capacity = " << arg << "." << mi.var <<
"value.capacity ();"
<< b << ".size = &" << arg << "." << mi.var << "size;"
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index d35a827..e00626a 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -1172,10 +1172,10 @@ traverse_object (type& c)
<< "{";
if (poly)
- os << "ODB_POTENTIALLY_UNUSED (top);";
+ os << "ODB_POTENTIALLY_UNUSED (top);"
+ << endl;
- os << endl
- << "using namespace " << db << ";"
+ os << "using namespace " << db << ";"
<< endl;
if (poly)
@@ -1461,13 +1461,25 @@ traverse_object (type& c)
<< "{"
<< "const object_type& obj (*objs[i]);"
<< "callback (db, obj, callback_event::pre_persist);"
- //@@ assumption: generate_grow is false
+ //@@ assumption: generate_grow is false or it only affects select (like
+ // in pgsql) so all we have to do is to increment image
+ // version if it grew.
//@@ assumption: insert_send_auto_id is false
- << "init (sts.image (i), obj, statement_insert" <<
- (versioned ? ", svm" : "") << ");"
+ << "image_type& im (sts.image (i));";
+
+ if (generate_grow)
+ os << "if (";
+
+ os << "init (im, obj, statement_insert" << (versioned ? ", svm" : "") << ")";
+
+ if (generate_grow)
+ os << " && i == 0)" << endl
+ << "im.version++";
+
+ os << ";"
<< "}";
- //@@ assumption: generate_grow is false
+ //@@ assumption: generate_grow: as above
os << "binding& imb (sts.insert_image_binding ());"
<< "if (imb.version == 0)"
<< "{"
@@ -1483,7 +1495,7 @@ traverse_object (type& c)
if (bv || auto_id)
{
os << "binding& idb (sts.id_image_binding ());"
- //@@ assumption: generate_grow is false
+ //@@ assumption: generate_grow: as above
<< "if (idb.version == 0)"
<< "{"
<< "bind (idb.bind, sts.id_image ());"
@@ -2212,9 +2224,24 @@ traverse_object (type& c)
if (opt != 0)
os << "const version_type& v (version (obj));";
- os << "init (sts.id_image (i), id (obj)" << (opt != 0 ? ", &v" : "") << ");"
- //@@ assumption: generate_grow false
- << "init (sts.image (i), obj, statement_update);"
+ os << "init (sts.id_image (i), id (obj)" << (opt != 0 ? ", &v" : "") << ");";
+
+ //@@ assumption: generate_grow is false or it only affects select (like
+ // in pgsql) so all we have to do is to increment image
+ // version if it grew.
+
+ os << "image_type& im (sts.image (i));";
+
+ if (generate_grow)
+ os << "if (";
+
+ os << "init (im, obj, statement_update" << (versioned ? ", svm" : "") << ")";
+
+ if (generate_grow)
+ os << " && i == 0)" << endl
+ << "im.version++";
+
+ os << ";"
<< "}";
// Update bindings.
@@ -2223,7 +2250,7 @@ traverse_object (type& c)
<< "binding& imb (sts.update_image_binding ());"
<< endl;
- //@@ assumption: generate_grow false
+ //@@ assumption: generate_grow: as above
//
os << "bool u (false);" // Avoid incrementing version twice.
<< "if (imb.version == 0)"
@@ -2234,7 +2261,7 @@ traverse_object (type& c)
<< "u = true;"
<< "}";
- //@@ assumption: generate_grow false
+ //@@ assumption: generate_grow: as above
//
os << "if (idb.version == 0)"
<< "{"
@@ -2452,7 +2479,8 @@ traverse_object (type& c)
<< "init (sts.id_image (i), *ids[i]);"
<< endl
<< "binding& idb (sts.id_image_binding ());"
- //@@ assumption: generate_grow false
+ //@@ assumption: generate_grow is false or it only affects select (like
+ // in pgsql).
<< "if (idb.version == 0)"
<< "{"
<< "bind (idb.bind, sts.id_image ());"
@@ -2836,7 +2864,8 @@ traverse_object (type& c)
<< "}";
os << "binding& idb (sts.id_image_binding ());"
- //@@ assumption: generate_grow false
+ //@@ assumption: generate_grow is false or it only affects select
+ // (like in pgsql).
<< "if (idb.version == 0)"
<< "{"
<< "bind (idb.bind, sts.id_image ());"