aboutsummaryrefslogtreecommitdiff
path: root/odb/relational
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-02-05 14:17:07 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-02-05 14:17:07 +0200
commit2ca4828d303fdd27c573429910f7a25fd1e3727c (patch)
treed2637c11861d44a634ecc09bbe88c3a3ff350b16 /odb/relational
parent8e69f40ab32dc8604b68f360ae30fa961ba036ee (diff)
Implement result modifiers in view query condition
Diffstat (limited to 'odb/relational')
-rw-r--r--odb/relational/mssql/source.cxx11
-rw-r--r--odb/relational/oracle/source.cxx15
-rw-r--r--odb/relational/processor.cxx14
-rw-r--r--odb/relational/source.cxx13
-rw-r--r--odb/relational/source.hxx9
-rw-r--r--odb/relational/sqlite/source.cxx9
6 files changed, 69 insertions, 2 deletions
diff --git a/odb/relational/mssql/source.cxx b/odb/relational/mssql/source.cxx
index ca36dfb..71bc40e 100644
--- a/odb/relational/mssql/source.cxx
+++ b/odb/relational/mssql/source.cxx
@@ -1179,6 +1179,17 @@ namespace relational
}
}
+ virtual string
+ from_trailer (type& c)
+ {
+ return c.get<view_query> ("query").for_update
+ ? " WITH (UPDLOCK)"
+ : "";
+ }
+
+ virtual string
+ select_trailer (type&) {return "";}
+
private:
// Go via the dynamic creation to get access to the constructor.
//
diff --git a/odb/relational/oracle/source.cxx b/odb/relational/oracle/source.cxx
index ea4a14b..71b032e 100644
--- a/odb/relational/oracle/source.cxx
+++ b/odb/relational/oracle/source.cxx
@@ -619,6 +619,21 @@ namespace relational
return r;
}
+
+ virtual string
+ select_trailer (type& c)
+ {
+ view_query const& vq (c.get<view_query> ("query"));
+
+ if (vq.for_update && vq.distinct)
+ {
+ error (vq.loc)
+ << "Oracle does not support FOR UPDATE with DISTINCT" << endl;
+ throw operation_failed ();
+ }
+
+ return base::select_trailer (c);
+ }
};
entry<class_> class_entry_;
}
diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx
index 7658725..16904b6 100644
--- a/odb/relational/processor.cxx
+++ b/odb/relational/processor.cxx
@@ -1298,11 +1298,23 @@ namespace relational
vq.kind = view_query::condition;
}
else
- vq.kind = view_query::runtime;
+ vq.kind = (vq.distinct || vq.for_update)
+ ? view_query::condition // The query(distinct) case.
+ : view_query::runtime;
}
else
vq.kind = has_o ? view_query::condition : view_query::runtime;
+ if ((vq.distinct || vq.for_update) && vq.kind != view_query::condition)
+ {
+ error (vq.loc)
+ << "result modifier specified for "
+ << (vq.kind == view_query::runtime ? "runtime" : "native")
+ << " query" << endl;
+
+ throw operation_failed ();
+ }
+
// We cannot have an incomplete query if there are not objects
// to derive the rest from.
//
diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx
index 39a210e..dc083bb 100644
--- a/odb/relational/source.cxx
+++ b/odb/relational/source.cxx
@@ -4770,6 +4770,8 @@ traverse_view (type& c)
if (!i->alias.empty ())
l += (need_alias_as ? " AS " : " ") + quote_id (i->alias);
+ l += from_trailer (c);
+
from.push_back (l);
continue;
}
@@ -4829,6 +4831,8 @@ traverse_view (type& c)
if (!alias.empty ())
l += (need_alias_as ? " AS " : " ") + quote_id (alias);
+ l += from_trailer (c);
+
from.push_back (l);
if (poly_depth != 1)
@@ -5539,7 +5543,7 @@ traverse_view (type& c)
string sep (versioned || query_optimize ? "\n" : " ");
os << "query_base_type r (" << endl
- << strlit ("SELECT" + sep);
+ << strlit ((vq.distinct ? "SELECT DISTINCT" : "SELECT") + sep);
for (statement_columns::const_iterator i (sc.begin ()),
e (sc.end ()); i != e;)
@@ -5632,6 +5636,13 @@ traverse_view (type& c)
<< "r += c.clause_prefix ();"
<< "r += c;"
<< "}";
+
+ string st (select_trailer (c));
+ if (!st.empty ())
+ {
+ os << "r += " << strlit (sep) << ";"
+ << "r += " << strlit (st) << ";";
+ }
}
else
{
diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx
index a725b6a..48d0e1d 100644
--- a/odb/relational/source.hxx
+++ b/odb/relational/source.hxx
@@ -6677,6 +6677,15 @@ namespace relational
<< "imb";
}
+ virtual string
+ from_trailer (type&) { return "";}
+
+ virtual string
+ select_trailer (type& c)
+ {
+ return c.get<view_query> ("query").for_update ? "FOR UPDATE" : "";
+ }
+
virtual void
traverse_view (type& c);
diff --git a/odb/relational/sqlite/source.cxx b/odb/relational/sqlite/source.cxx
index 3dfaae2..0824eb2 100644
--- a/odb/relational/sqlite/source.cxx
+++ b/odb/relational/sqlite/source.cxx
@@ -246,6 +246,15 @@ namespace relational
{
os << im << "null = true;";
}
+
+ virtual string
+ select_trailer (type&)
+ {
+ // SQLite has not support for FOR UPDATE and since this is an
+ // optimization, we simply ignore it.
+ //
+ return "";
+ }
};
entry<class_> class_entry_;
}