From b5ed13549a87dccb56f756d6fbc5f7bf537e9640 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 30 Aug 2013 06:05:32 +0200 Subject: Statement processing/optimization base work --- odb/pgsql/container-statements.hxx | 6 ++ odb/pgsql/container-statements.txx | 2 + odb/pgsql/database.cxx | 2 + odb/pgsql/forward.hxx | 3 +- odb/pgsql/no-id-object-statements.hxx | 1 + odb/pgsql/polymorphic-object-statements.hxx | 6 ++ odb/pgsql/query.cxx | 16 ++-- odb/pgsql/section-statements.hxx | 3 + odb/pgsql/simple-object-statements.hxx | 4 + odb/pgsql/statement.cxx | 140 ++++++++++++++++++++++++---- odb/pgsql/statement.hxx | 28 +++++- 11 files changed, 181 insertions(+), 30 deletions(-) diff --git a/odb/pgsql/container-statements.hxx b/odb/pgsql/container-statements.hxx index 3fcc002..d77eec9 100644 --- a/odb/pgsql/container-statements.hxx +++ b/odb/pgsql/container-statements.hxx @@ -121,6 +121,7 @@ namespace odb conn_, insert_name_, insert_text_, + versioned_, // Process if versioned. insert_types_, insert_count_, insert_image_binding_, @@ -140,6 +141,8 @@ namespace odb conn_, select_name_, select_text_, + versioned_, // Process if versioned. + false, // Don't optimize. id_types_, id_binding_.count, id_binding_, @@ -201,6 +204,8 @@ namespace odb const char* delete_name_; const char* delete_text_; + bool versioned_; + details::shared_ptr insert_; details::shared_ptr select_; details::shared_ptr delete_; @@ -313,6 +318,7 @@ namespace odb this->conn_, update_name_, update_text_, + this->versioned_, // Process if versioned. update_types_, update_count_, update_image_binding_, diff --git a/odb/pgsql/container-statements.txx b/odb/pgsql/container-statements.txx index 2fd4d15..1af19bb 100644 --- a/odb/pgsql/container-statements.txx +++ b/odb/pgsql/container-statements.txx @@ -106,6 +106,8 @@ namespace odb this->delete_name_ = traits::delete_name; this->delete_text_ = traits::delete_statement; + + this->versioned_ = traits::versioned; } // smart_container_statements_impl diff --git a/odb/pgsql/database.cxx b/odb/pgsql/database.cxx index 61cc29e..389422b 100644 --- a/odb/pgsql/database.cxx +++ b/odb/pgsql/database.cxx @@ -289,6 +289,8 @@ namespace odb select_statement st (c, "odb_database_schema_version", text.c_str (), + false, + false, param_types, 1, param, diff --git a/odb/pgsql/forward.hxx b/odb/pgsql/forward.hxx index 470462e..95c59bd 100644 --- a/odb/pgsql/forward.hxx +++ b/odb/pgsql/forward.hxx @@ -43,7 +43,8 @@ namespace odb { statement_select, statement_insert, - statement_update + statement_update, + statement_delete }; class binding; diff --git a/odb/pgsql/no-id-object-statements.hxx b/odb/pgsql/no-id-object-statements.hxx index 7b3c74b..a95b6c5 100644 --- a/odb/pgsql/no-id-object-statements.hxx +++ b/odb/pgsql/no-id-object-statements.hxx @@ -87,6 +87,7 @@ namespace odb conn_, object_traits::persist_statement_name, object_traits::persist_statement, + object_traits::versioned, // Process if versioned. object_traits::persist_statement_types, insert_column_count, insert_image_binding_, diff --git a/odb/pgsql/polymorphic-object-statements.hxx b/odb/pgsql/polymorphic-object-statements.hxx index c538c49..93f711a 100644 --- a/odb/pgsql/polymorphic-object-statements.hxx +++ b/odb/pgsql/polymorphic-object-statements.hxx @@ -110,6 +110,8 @@ namespace odb this->conn_, object_traits::find_discriminator_statement_name, object_traits::find_discriminator_statement, + false, // Doesn't need to be processed. + false, // Don't optimize. object_traits::find_statement_types, // The same as find (id). id_column_count, discriminator_id_image_binding_, @@ -309,6 +311,7 @@ namespace odb conn_, object_traits::persist_statement_name, object_traits::persist_statement, + object_traits::versioned, // Process if versioned. object_traits::persist_statement_types, insert_column_count, insert_image_binding_, @@ -331,6 +334,8 @@ namespace odb conn_, object_traits::find_statement_names[i], object_traits::find_statements[i], + object_traits::versioned, // Process if versioned. + false, // Don't optimize. object_traits::find_statement_types, id_column_count, root_statements_.id_image_binding (), @@ -350,6 +355,7 @@ namespace odb conn_, object_traits::update_statement_name, object_traits::update_statement, + object_traits::versioned, // Process if versioned. object_traits::update_statement_types, update_column_count + id_column_count, update_image_binding_, diff --git a/odb/pgsql/query.cxx b/odb/pgsql/query.cxx index d054450..4cbad67 100644 --- a/odb/pgsql/query.cxx +++ b/odb/pgsql/query.cxx @@ -167,8 +167,8 @@ namespace odb // We don't want extra spaces after '(' as well as before ',' // and ')'. // - if (last != ' ' && last != '(' && - first != ' ' && first != ',' && first != ')') + if (last != ' ' && last != '\n' && last != '(' && + first != ' ' && first != '\n' && first != ',' && first != ')') s += ' '; s += q; @@ -276,7 +276,7 @@ namespace odb // It either has to be an exact match, or there should be // a whitespace following the keyword. // - if (s.size () == n || s[n] == ' ' || s[n] =='\t') + if (s.size () == n || s[n] == ' ' || s[n] == '\n' || s[n] =='\t') return true; } @@ -336,7 +336,7 @@ namespace odb { case clause_part::kind_column: { - if (last != ' ' && last != '(') + if (last != ' ' && last != '\n' && last != '(') r += ' '; r += i->part; @@ -344,7 +344,7 @@ namespace odb } case clause_part::kind_param: { - if (last != ' ' && last != '(') + if (last != ' ' && last != '\n' && last != '(') r += ' '; ostringstream os; @@ -375,8 +375,8 @@ namespace odb const string& p (i->part); char first (!p.empty () ? p[0] : ' '); - if (last != ' ' && last != '(' && - first != ' ' && first != ',' && first != ')') + if (last != ' ' && last != '\n' && last != '(' && + first != ' ' && first != '\n' && first != ',' && first != ')') r += ' '; r += p; @@ -384,7 +384,7 @@ namespace odb } case clause_part::kind_bool: { - if (last != ' ' && last != '(') + if (last != ' ' && last != '\n' && last != '(') r += ' '; r += i->bool_part ? "TRUE" : "FALSE"; diff --git a/odb/pgsql/section-statements.hxx b/odb/pgsql/section-statements.hxx index b2f5c7b..d75fd66 100644 --- a/odb/pgsql/section-statements.hxx +++ b/odb/pgsql/section-statements.hxx @@ -104,6 +104,8 @@ namespace odb conn_, traits::select_name, traits::select_statement, + traits::versioned, // Process if versioned. + false, // Don't optimize. id_types_, id_column_count, id_binding_, @@ -123,6 +125,7 @@ namespace odb conn_, traits::update_name, traits::update_statement, + traits::versioned, // Process if versioned. traits::update_types, update_column_count + id_column_count + managed_optimistic_update_column_count, diff --git a/odb/pgsql/simple-object-statements.hxx b/odb/pgsql/simple-object-statements.hxx index 5840c26..a8d7ce3 100644 --- a/odb/pgsql/simple-object-statements.hxx +++ b/odb/pgsql/simple-object-statements.hxx @@ -375,6 +375,7 @@ namespace odb conn_, object_traits::persist_statement_name, object_traits::persist_statement, + object_traits::versioned, // Process if versioned. object_traits::persist_statement_types, insert_column_count, insert_image_binding_, @@ -394,6 +395,8 @@ namespace odb conn_, object_traits::find_statement_name, object_traits::find_statement, + object_traits::versioned, // Process if versioned. + false, // Don't optimize. object_traits::find_statement_types, id_column_count, id_image_binding_, @@ -413,6 +416,7 @@ namespace odb conn_, object_traits::update_statement_name, object_traits::update_statement, + object_traits::versioned, // Process if versioned. object_traits::update_statement_types, update_column_count + id_column_count, update_image_binding_, diff --git a/odb/pgsql/statement.cxx b/odb/pgsql/statement.cxx index 1bf8d16..feebe06 100644 --- a/odb/pgsql/statement.cxx +++ b/odb/pgsql/statement.cxx @@ -89,14 +89,24 @@ namespace odb statement (connection_type& conn, const string& name, const string& text, + statement_kind sk, + const binding* process, + bool optimize, const Oid* types, size_t types_count) : conn_ (conn), name_copy_ (name), name_ (name_copy_.c_str ()), - text_copy_ (text), text_ (text_copy_.c_str ()), deallocated_ (false) { - init (types, types_count); + if (process == 0) + { + text_copy_ = text; + text_ = text_copy_.c_str (); + } + else + text_ = text.c_str (); // Temporary, see init(). + + init (sk, process, optimize, types, types_count); // // If any code after this line throws, the statement will be leaked @@ -108,6 +118,9 @@ namespace odb statement (connection_type& conn, const char* name, const char* text, + statement_kind sk, + const binding* process, + bool optimize, bool copy, const Oid* types, size_t types_count) @@ -117,16 +130,19 @@ namespace odb { name_copy_ = name; name_ = name_copy_.c_str (); - text_copy_ = text; - text_ = text_copy_.c_str (); } else - { name_ = name; - text_ = text; + + if (process == 0 && copy) + { + text_copy_ = text; + text_ = text_copy_.c_str (); } + else + text_ = text; // Potentially temporary, see init(). - init (types, types_count); + init (sk, process, optimize, types, types_count); // // If any code after this line throws, the statement will be leaked @@ -135,8 +151,42 @@ namespace odb } void statement:: - init (const Oid* types, size_t types_count) + init (statement_kind sk, + const binding* proc, + bool optimize, + const Oid* types, + size_t types_count) { + if (proc != 0) + { + switch (sk) + { + case statement_select: + process_select (text_, + &proc->bind->buffer, proc->count, sizeof (bind), + '"', '"', + optimize, + text_copy_); + break; + case statement_insert: + process_insert (text_, + &proc->bind->buffer, proc->count, sizeof (bind), + '$', + text_copy_); + break; + case statement_update: + process_update (text_, + &proc->bind->buffer, proc->count, sizeof (bind), + '$', + text_copy_); + break; + case statement_delete: + assert (false); + } + + text_ = text_copy_.c_str (); + } + { odb::tracer* t; if ((t = conn_.transaction_tracer ()) || @@ -396,12 +446,17 @@ namespace odb select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process, + bool optimize, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param, binding& result) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_select, + (process ? &result : 0), optimize, + types, types_count), param_ (¶m), native_param_ (&native_param), result_ (result), @@ -414,13 +469,18 @@ namespace odb select_statement (connection_type& conn, const char* name, const char* text, + bool process, + bool optimize, const Oid* types, std::size_t types_count, binding& param, native_binding& native_param, binding& result, bool copy) - : statement (conn, name, text, copy, types, types_count), + : statement (conn, + name, text, statement_select, + (process ? &result : 0), optimize, copy, + types, types_count), param_ (¶m), native_param_ (&native_param), result_ (result), @@ -433,8 +493,13 @@ namespace odb select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process, + bool optimize, binding& result) - : statement (conn, name, text, 0, 0), + : statement (conn, + name, text, statement_select, + (process ? &result : 0), optimize, + 0, 0), param_ (0), native_param_ (0), result_ (result), @@ -447,9 +512,14 @@ namespace odb select_statement (connection_type& conn, const char* name, const char* text, + bool process, + bool optimize, binding& result, bool copy) - : statement (conn, name, text, copy, 0, 0), + : statement (conn, + name, text, statement_select, + (process ? &result : 0), optimize, copy, + 0, 0), param_ (0), native_param_ (0), result_ (result), @@ -462,11 +532,16 @@ namespace odb select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process, + bool optimize, const Oid* types, std::size_t types_count, native_binding& native_param, binding& result) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_select, + (process ? &result : 0), optimize, + types, types_count), param_ (0), native_param_ (&native_param), result_ (result), @@ -568,12 +643,16 @@ namespace odb insert_statement (connection_type& conn, const string& name, const string& text, + bool process, const Oid* types, size_t types_count, binding& param, native_binding& native_param, bool returning) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_insert, + (process ? ¶m : 0), false, + types, types_count), param_ (param), native_param_ (native_param), returning_ (returning) @@ -584,13 +663,17 @@ namespace odb insert_statement (connection_type& conn, const char* name, const char* text, + bool process, const Oid* types, size_t types_count, binding& param, native_binding& native_param, bool returning, bool copy) - : statement (conn, name, text, copy, types, types_count), + : statement (conn, + name, text, statement_insert, + (process ? ¶m : 0), false, copy, + types, types_count), param_ (param), native_param_ (native_param), returning_ (returning) @@ -687,11 +770,15 @@ namespace odb update_statement (connection_type& conn, const string& name, const string& text, + bool process, const Oid* types, size_t types_count, binding& param, native_binding& native_param) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_update, + (process ? ¶m : 0), false, + types, types_count), param_ (param), native_param_ (native_param) { @@ -701,12 +788,16 @@ namespace odb update_statement (connection_type& conn, const char* name, const char* text, + bool process, const Oid* types, size_t types_count, binding& param, native_binding& native_param, bool copy) - : statement (conn, name, text, copy, types, types_count), + : statement (conn, + name, text, statement_update, + (process ? ¶m : 0), false, copy, + types, types_count), param_ (param), native_param_ (native_param) { @@ -757,7 +848,10 @@ namespace odb size_t types_count, binding& param, native_binding& native_param) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_delete, + 0, false, + types, types_count), param_ (¶m), native_param_ (native_param) { @@ -772,7 +866,10 @@ namespace odb binding& param, native_binding& native_param, bool copy) - : statement (conn, name, text, copy, types, types_count), + : statement (conn, + name, text, statement_delete, + 0, false, copy, + types, types_count), param_ (¶m), native_param_ (native_param) { @@ -785,7 +882,10 @@ namespace odb const Oid* types, size_t types_count, native_binding& native_param) - : statement (conn, name, text, types, types_count), + : statement (conn, + name, text, statement_delete, + 0, false, + types, types_count), param_ (0), native_param_ (native_param) { diff --git a/odb/pgsql/statement.hxx b/odb/pgsql/statement.hxx index 8effbe1..4cc1f42 100644 --- a/odb/pgsql/statement.hxx +++ b/odb/pgsql/statement.hxx @@ -71,22 +71,34 @@ namespace odb bool truncated = false); protected: + // We keep two versions to take advantage of std::string COW. + // statement (connection_type&, const std::string& name, const std::string& text, + statement_kind, + const binding* process, + bool optimize, const Oid* types, std::size_t types_count); statement (connection_type&, const char* name, const char* text, + statement_kind, + const binding* process, + bool optimize, bool copy_name_text, const Oid* types, std::size_t types_count); private: void - init (const Oid* types, std::size_t types_count); + init (statement_kind, + const binding* process, + bool optimize, + const Oid* types, + std::size_t types_count); protected: connection_type& conn_; @@ -110,6 +122,8 @@ namespace odb select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process_text, + bool optimize_text, const Oid* types, std::size_t types_count, binding& param, @@ -119,6 +133,8 @@ namespace odb select_statement (connection_type& conn, const char* name, const char* stmt, + bool process_text, + bool optimize_text, const Oid* types, std::size_t types_count, binding& param, @@ -129,17 +145,23 @@ namespace odb select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process_text, + bool optimize_text, binding& result); select_statement (connection_type& conn, const char* name, const char* text, + bool process_text, + bool optimize_text, binding& result, bool copy_name_text = true); select_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process_text, + bool optimize_text, const Oid* types, std::size_t types_count, native_binding& native_param, @@ -240,6 +262,7 @@ namespace odb insert_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process_text, const Oid* types, std::size_t types_count, binding& param, @@ -249,6 +272,7 @@ namespace odb insert_statement (connection_type& conn, const char* name, const char* text, + bool process_text, const Oid* types, std::size_t types_count, binding& param, @@ -289,6 +313,7 @@ namespace odb update_statement (connection_type& conn, const std::string& name, const std::string& text, + bool process_text, const Oid* types, std::size_t types_count, binding& param, @@ -297,6 +322,7 @@ namespace odb update_statement (connection_type& conn, const char* name, const char* text, + bool process_text, const Oid* types, std::size_t types_count, binding& param, -- cgit v1.1