summaryrefslogtreecommitdiff
path: root/sql/vers_utils.h
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2017-06-15 16:02:32 +0300
committerAleksey Midenkov <midenok@gmail.com>2017-06-19 15:21:39 +0300
commit448374a228aee3cd867d89f1a1eae9884f5bf434 (patch)
treeeb21e9fc41102454aacc899fb0443601e9aef0b1 /sql/vers_utils.h
parentefaa0d66dafc44d994054c7d6ff160cb295a0bf6 (diff)
downloadmariadb-git-448374a228aee3cd867d89f1a1eae9884f5bf434.tar.gz
SQL, IB: (0.10) VTMD tracking [closes #124]
IB: Fixes in logic when to do versioned or usual row updates. Now it is able to do unversioned updates for versioned tables just by disabling `TABLE_SHARE::versioned` flag. SQL: DDL tracking for: * RENAME TABLE, ALTER TABLE .. RENAME TO; * DROP TABLE; * data-modifying operations (f.ex. ALTER TABLE .. ADD/DROP COLUMN).
Diffstat (limited to 'sql/vers_utils.h')
-rw-r--r--sql/vers_utils.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/sql/vers_utils.h b/sql/vers_utils.h
new file mode 100644
index 00000000000..ee08fcbb2bc
--- /dev/null
+++ b/sql/vers_utils.h
@@ -0,0 +1,165 @@
+#ifndef VERS_UTILS_INCLUDED
+#define VERS_UTILS_INCLUDED
+
+#include "table.h"
+#include "sql_class.h"
+
+class MDL_auto_lock
+{
+ THD *thd;
+ TABLE_LIST &table;
+ bool error;
+
+public:
+ MDL_auto_lock(THD *_thd, TABLE_LIST &_table) :
+ thd(_thd), table(_table)
+ {
+ DBUG_ASSERT(thd);
+ table.mdl_request.init(MDL_key::TABLE, table.db, table.table_name, MDL_EXCLUSIVE, MDL_EXPLICIT);
+ error= thd->mdl_context.acquire_lock(&table.mdl_request, thd->variables.lock_wait_timeout);
+ }
+ ~MDL_auto_lock()
+ {
+ if (!error)
+ {
+ DBUG_ASSERT(table.mdl_request.ticket);
+ thd->mdl_context.release_lock(table.mdl_request.ticket);
+ table.mdl_request.ticket= NULL;
+ }
+ }
+ bool acquire_error() const { return error; }
+};
+
+struct Compare_strncmp
+{
+ int operator()(const LEX_STRING& a, const LEX_STRING& b) const
+ {
+ return strncmp(a.str, b.str, a.length);
+ }
+ static CHARSET_INFO* charset()
+ {
+ return system_charset_info;
+ }
+};
+
+template <CHARSET_INFO* &CS= system_charset_info>
+struct Compare_my_strcasecmp
+{
+ int operator()(const LEX_STRING& a, const LEX_STRING& b) const
+ {
+ DBUG_ASSERT(a.str[a.length] == 0 && b.str[b.length] == 0);
+ return my_strcasecmp(CS, a.str, b.str);
+ }
+ static CHARSET_INFO* charset()
+ {
+ return CS;
+ }
+};
+
+typedef Compare_my_strcasecmp<files_charset_info> Compare_fs;
+typedef Compare_my_strcasecmp<table_alias_charset> Compare_t;
+
+struct LEX_STRING_u : public LEX_STRING
+{
+ LEX_STRING_u()
+ {
+ str= NULL;
+ LEX_STRING::length= 0;
+ }
+ LEX_STRING_u(const char *_str, uint32 _len, CHARSET_INFO *)
+ {
+ str= const_cast<char *>(_str);
+ LEX_STRING::length= _len;
+ }
+ uint32 length() const
+ {
+ return LEX_STRING::length;
+ }
+ const char *ptr() const
+ {
+ return LEX_STRING::str;
+ }
+ const LEX_STRING& lex_string() const
+ {
+ return *this;
+ }
+};
+
+template <class Compare= Compare_strncmp, class Storage= LEX_STRING_u>
+struct XString : public Storage
+{
+public:
+ XString() {}
+ XString(char *_str, size_t _len) :
+ Storage(_str, _len, Compare::charset())
+ {
+ }
+ XString(LEX_STRING& src) :
+ Storage(src.str, src.length, Compare::charset())
+ {
+ }
+ XString(char *_str) :
+ Storage(_str, strlen(_str), Compare::charset())
+ {
+ }
+ bool operator== (const XString& b) const
+ {
+ return Storage::length() == b.length() && 0 == Compare()(this->lex_string(), b.lex_string());
+ }
+ bool operator!= (const XString& b) const
+ {
+ return !(*this == b);
+ }
+ operator const char* () const
+ {
+ return Storage::ptr();
+ }
+};
+
+typedef XString<> LString;
+typedef XString<Compare_fs> LString_fs;
+
+typedef XString<Compare_strncmp, String> SString;
+typedef XString<Compare_fs, String> SString_fs;
+typedef XString<Compare_t, String> SString_t;
+
+
+#define XSTRING_WITH_LEN(X) (X).ptr(), (X).length()
+#define DB_WITH_LEN(X) (X).db, (X).db_length
+#define TABLE_NAME_WITH_LEN(X) (X).table_name, (X).table_name_length
+
+
+class Local_da : public Diagnostics_area
+{
+ THD *thd;
+ uint sql_error;
+ Diagnostics_area *saved_da;
+
+public:
+ Local_da(THD *_thd, uint _sql_error= 0) :
+ Diagnostics_area(_thd->query_id, false, true),
+ thd(_thd),
+ sql_error(_sql_error),
+ saved_da(_thd->get_stmt_da())
+ {
+ thd->set_stmt_da(this);
+ }
+ ~Local_da()
+ {
+ if (saved_da)
+ finish();
+ }
+ void finish()
+ {
+ DBUG_ASSERT(saved_da && thd);
+ thd->set_stmt_da(saved_da);
+ if (is_error())
+ my_error(sql_error ? sql_error : sql_errno(), MYF(0), message());
+ if (warn_count() > error_count())
+ saved_da->copy_non_errors_from_wi(thd, get_warning_info());
+ saved_da= NULL;
+ }
+};
+
+
+#endif // VERS_UTILS_INCLUDED