aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2013-01-14 18:02:32 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2013-01-14 18:02:32 +0200
commitb069af3f557dd3ce94d2d665fa5759279aa3780f (patch)
tree6a7c45a1796dd9306f6345aa0932127d71f279d7
parent0e6be616e40c86ff03df7c0806bcbd0cc3c4489f (diff)
Fix bug in handling polymorphic derived classes without any value members
-rw-r--r--odb/relational/source.cxx78
1 files changed, 51 insertions, 27 deletions
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 0ec7cc4..58e40e7 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -525,6 +525,13 @@ traverse_object (type& c)
<< endl;
}
+ // Index of the first empty SELECT statement in poly-derived
+ // statement list. All subsequent statements are also empty.
+ // The first statement can never be empty (contains id and
+ // type_id).
+ //
+ size_t empty_depth (0);
+
if (id != 0)
{
instance<object_columns_list> id_cols;
@@ -551,38 +558,43 @@ traverse_object (type& c)
find_column_counts[poly_depth - d] = sc.size ();
}
- os << strlit ("SELECT ") << endl;
-
- for (statement_columns::const_iterator i (sc.begin ()),
- e (sc.end ()); i != e;)
+ if (sc.size () != 0)
{
- string const& c (i->column);
- os << strlit (c + (++i != e ? "," : "")) << endl;
- }
+ os << strlit ("SELECT ") << endl;
- os << strlit (" FROM " + qtable) << endl;
+ for (statement_columns::const_iterator i (sc.begin ()),
+ e (sc.end ()); i != e;)
+ {
+ string const& c (i->column);
+ os << strlit (c + (++i != e ? "," : "")) << endl;
+ }
- if (poly_derived)
- {
- instance<polymorphic_object_joins> j (c, d);
- j->traverse (c);
- }
+ os << strlit (" FROM " + qtable) << endl;
- bool f (false); // @@ (im)perfect forwarding
- instance<object_joins> j (c, f, d); // @@ (im)perfect forwarding
- j->traverse (c);
+ if (poly_derived)
+ {
+ instance<polymorphic_object_joins> j (c, d);
+ j->traverse (c);
+ }
- instance<query_parameters> qp (table);
- for (object_columns_list::iterator b (id_cols->begin ()), i (b);
- i != id_cols->end (); ++i)
- {
- if (i != b)
- os << endl;
+ bool f (false); // @@ (im)perfect forwarding
+ instance<object_joins> j (c, f, d); // @@ (im)perfect forwarding
+ j->traverse (c);
- os << strlit ((i == b ? " WHERE " : " AND ") +
- qtable + "." + quote_id (i->name) + "=" +
- convert_to (qp->next (), i->type, *i->member));
+ instance<query_parameters> qp (table);
+ for (object_columns_list::iterator b (id_cols->begin ()), i (b);
+ i != id_cols->end (); ++i)
+ {
+ if (i != b)
+ os << endl;
+
+ os << strlit ((i == b ? " WHERE " : " AND ") +
+ qtable + "." + quote_id (i->name) + "=" +
+ convert_to (qp->next (), i->type, *i->member));
+ }
}
+ else
+ os << strlit (""); // Empty SELECT statement.
if (abst)
break;
@@ -605,11 +617,14 @@ traverse_object (type& c)
os << "const std::size_t " << traits << "::find_column_counts[] ="
<< "{";
- for (std::vector<size_t>::iterator i (find_column_counts.begin ()),
- e (find_column_counts.end ()); i != e;)
+ for (std::vector<size_t>::iterator b (find_column_counts.begin ()),
+ i (b), e (find_column_counts.end ()); i != e;)
{
os << *i << "UL";
+ if (*i == 0 && empty_depth == 0)
+ empty_depth = i - b;
+
if (++i != e)
os << ',' << endl;
}
@@ -2397,6 +2412,12 @@ traverse_object (type& c)
<< "d = depth - d;" // Convert to distance from derived.
<< endl;
+ // Avoid trying to execute an empty SELECT statement.
+ //
+ if (empty_depth != 0)
+ os << "if (d > " << (poly_depth - empty_depth) << "UL)"
+ << "{";
+
os << "if (!find_ (sts, 0, d))" << endl
<< "throw object_not_persistent ();" // Database inconsistency.
<< endl;
@@ -2415,6 +2436,9 @@ traverse_object (type& c)
if (delay_freeing_statement_result)
os << "ar.free ();";
+ if (empty_depth != 0)
+ os << "}";
+
os << "load_ (sts, obj, d);"
<< "}";
}