diff options
-rw-r--r-- | odb/context.hxx | 3 | ||||
-rw-r--r-- | odb/relational/processor.cxx | 29 | ||||
-rw-r--r-- | odb/relational/source.cxx | 40 | ||||
-rw-r--r-- | odb/relational/source.hxx | 3 |
4 files changed, 58 insertions, 17 deletions
diff --git a/odb/context.hxx b/odb/context.hxx index fe9b533..50d47f2 100644 --- a/odb/context.hxx +++ b/odb/context.hxx @@ -178,7 +178,8 @@ struct view_query enum kind_type { runtime, - complete, + complete_select, // SELECT query. + complete_execute, // Stored procedure call. condition }; diff --git a/odb/relational/processor.cxx b/odb/relational/processor.cxx index 5ac97f5..0c27971 100644 --- a/odb/relational/processor.cxx +++ b/odb/relational/processor.cxx @@ -1234,22 +1234,35 @@ namespace relational if (!vq.literal.empty ()) { string q (upcase (vq.literal)); - vq.kind = (q.compare (0, 7, "SELECT ") == 0) - ? view_query::complete - : view_query::condition; + + if (q.compare (0, 7, "SELECT ") == 0) + vq.kind = view_query::complete_select; + else if (q.compare (0, 5, "EXEC ") == 0 || + q.compare (0, 5, "CALL ") == 0 || + q.compare (0, 8, "EXECUTE ") == 0) + vq.kind = view_query::complete_execute; + else + vq.kind = view_query::condition; } else if (!vq.expr.empty ()) { // If the first token in the expression is a string and - // it starts with "SELECT " or is equal to "SELECT", then - // we have a complete query. + // it starts with "SELECT " or is equal to "SELECT" or + // one of the stored procedure call keywords, then we + // have a complete query. // if (vq.expr.front ().type == CPP_STRING) { string q (upcase (vq.expr.front ().literal)); - vq.kind = (q.compare (0, 7, "SELECT ") == 0 || q == "SELECT") - ? view_query::complete - : view_query::condition; + + if (q.compare (0, 7, "SELECT ") == 0 || q == "SELECT") + vq.kind = view_query::complete_select; + else if (q.compare (0, 5, "EXEC ") == 0 || q == "EXEC" || + q.compare (0, 5, "CALL ") == 0 || q == "CALL" || + q.compare (0, 8, "EXECUTE ") == 0 || q == "EXECUTE") + vq.kind = view_query::complete_execute; + else + vq.kind = view_query::condition; } else vq.kind = view_query::condition; diff --git a/odb/relational/source.cxx b/odb/relational/source.cxx index 210d04b..b1d2a3d 100644 --- a/odb/relational/source.cxx +++ b/odb/relational/source.cxx @@ -3079,11 +3079,13 @@ traverse_view (type& c) << "query_statement (const query_base_type& q)" << "{"; - if (vq.kind == view_query::complete) + if (vq.kind == view_query::complete_select || + vq.kind == view_query::complete_execute) { os << "query_base_type r (" << endl; bool ph (false); + bool pred (vq.kind == view_query::complete_select); if (!vq.literal.empty ()) { @@ -3099,9 +3101,21 @@ traverse_view (type& c) if (p != string::npos) { ph = true; - os << strlit (string (vq.literal, 0, p + 1)) << " +" << endl - << "(q.empty () ? query_base_type::true_expr : q) +" << endl - << strlit (string (vq.literal, p + 2)); + // For the SELECT query we keep the parenthesis in (?) and + // also handle the case where the query expression is empty. + // + if (pred) + os << strlit (string (vq.literal, 0, p + 1)) << " +" << endl + << "(q.empty () ? query_base_type::true_expr : q) +" << endl + << strlit (string (vq.literal, p + 2)); + else + { + os << strlit (string (vq.literal, 0, p)) << " + q"; + + p += 3; + if (p != vq.literal.size ()) + os << strlit (string (vq.literal, p)); + } } else os << strlit (vq.literal); @@ -3115,7 +3129,7 @@ traverse_view (type& c) // os << "// From " << location_string (vq.loc, true) << endl << translate_expression ( - c, vq.expr, scope, vq.loc, "query", &ph).value; + c, vq.expr, scope, vq.loc, "query", &ph, pred).value; } os << ");"; @@ -4237,7 +4251,8 @@ namespace relational semantics::scope& scope, location_t loc, string const& prag, - bool* placeholder) + bool* placeholder, + bool predicate) { // This code is similar to translate() from context.cxx. // @@ -4432,8 +4447,19 @@ namespace relational if (tt == CPP_CLOSE_PAREN) { - r += "q.empty () ? query_base_type::true_expr : q"; *placeholder = true; + + // Predicate is true if this is a SELECT statement clause. + // Otherwise it is a stored procedure parameters. + // + if (predicate) + r += "q.empty () ? query_base_type::true_expr : q"; + else + { + r.resize (r.size () - 1); // Remove opening paren. + r += "q"; + break; // Skip the closing paren as well. + } } else { diff --git a/odb/relational/source.hxx b/odb/relational/source.hxx index 0b50788..37328c8 100644 --- a/odb/relational/source.hxx +++ b/odb/relational/source.hxx @@ -3873,7 +3873,8 @@ namespace relational semantics::scope& start_scope, location_t loc, string const& prag, - bool* placeholder = 0); + bool* placeholder = 0, + bool predicate = true); // // composite // |