revision-id: 890e0278706768e18b28582329418c8943d6a6bd (mariadb-10.4.1-94-g890e027)
parent(s): 294d9bf2484abfd3409d4ac25a3b3b695d66b0ec
committer: Alexey Botchkov
timestamp: 2019-01-17 10:30:09 +0400
message:
MDEV-5313 Improving audit api.
json_t unittest added.
---
unittest/strings/json-t.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/unittest/strings/json-t.c b/unittest/strings/json-t.c
new file mode 100644
index 0000000..8af8636
--- /dev/null
+++ b/unittest/strings/json-t.c
@@ -0,0 +1,58 @@
+/* Copyright (c) 2019, MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include <tap.h>
+#include <my_sys.h>
+#include <json_lib.h>
+
+int main()
+{
+ const char *json="{\"int\":1, \"str\":\"foo bar\", "
+ "\"array\":[10,20,{\"c\":\"d\"}],\"bool\":false}";
+ const char *json_ar="[1, \"foo bar\", " "[10,20,{\"c\":\"d\"}], false]";
+ enum json_types value_type;
+ const char *value_start;
+ int value_len;
+
+ plan(10);
+
+#define do_json(V) \
+ do { \
+ value_type= json_get_object_key(json, json+strlen(json), \
+ V, V + (sizeof(V) - 1),&value_start, &value_len); \
+ ok(value_type != JSV_BAD_JSON, V); \
+ diag("type=%d, value=\"%.*s\"", value_type, (int)value_len, value_start); \
+ } while(0)
+#define do_json_ar(N) \
+ do { \
+ value_type= json_get_array_item(json_ar, json_ar+strlen(json_ar), \
+ N, &value_start, &value_len); \
+ ok(value_type != JSV_BAD_JSON, #N); \
+ diag("type=%d, value=\"%.*s\"", value_type, (int)value_len, value_start); \
+ } while(0)
+
+ do_json("int");
+ do_json("str");
+ do_json("bool");
+ do_json("c");
+ do_json("array");
+
+ do_json_ar(0);
+ do_json_ar(1);
+ do_json_ar(2);
+ do_json_ar(3);
+ do_json_ar(4);
+ return exit_status();
+}
1
0
revision-id: 294d9bf2484abfd3409d4ac25a3b3b695d66b0ec (mariadb-10.4.1-93-g294d9bf)
parent(s): edba0470803bf2277b5509af3b978f042c0b7204
committer: Alexey Botchkov
timestamp: 2019-01-17 03:52:52 +0400
message:
MDEV-5313 Improving audit api.
JSON api implementations and tests pushed.
sql_acl.cc fixed with the new function names.
---
include/json_lib.h | 4 -
include/mysql/plugin_audit.h.pp | 20 ++--
include/mysql/plugin_auth.h.pp | 20 ++--
include/mysql/plugin_encryption.h.pp | 20 ++--
include/mysql/plugin_ftparser.h.pp | 20 ++--
include/mysql/plugin_password_validation.h.pp | 20 ++--
include/mysql/service_json.h | 20 ++--
sql/sql_acl.cc | 30 +++---
strings/json_lib.c | 145 +++++++++++++++++---------
unittest/strings/CMakeLists.txt | 2 +-
10 files changed, 174 insertions(+), 127 deletions(-)
diff --git a/include/json_lib.h b/include/json_lib.h
index 0f8cff7..a347538 100644
--- a/include/json_lib.h
+++ b/include/json_lib.h
@@ -425,10 +425,6 @@ int json_path_compare(const json_path_t *a, const json_path_t *b,
int json_valid(const char *js, size_t js_len, CHARSET_INFO *cs);
-int json_get_object_by_key(const char *js, size_t js_len,
- const char *key, size_t key_len,
- enum json_value_types *value_type,
- const char **value_start, size_t *value_len);
#ifdef __cplusplus
}
#endif
diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp
index 0588b21..47f07ae 100644
--- a/include/mysql/plugin_audit.h.pp
+++ b/include/mysql/plugin_audit.h.pp
@@ -388,33 +388,33 @@ enum json_types
};
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
char *res, char *res_end);
} *json_service;
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index cfb9201..f9d01a8 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -388,33 +388,33 @@ enum json_types
};
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
char *res, char *res_end);
} *json_service;
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp
index 7761a3e..e55a034 100644
--- a/include/mysql/plugin_encryption.h.pp
+++ b/include/mysql/plugin_encryption.h.pp
@@ -388,33 +388,33 @@ enum json_types
};
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
char *res, char *res_end);
} *json_service;
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp
index 2e77597..f9d9844 100644
--- a/include/mysql/plugin_ftparser.h.pp
+++ b/include/mysql/plugin_ftparser.h.pp
@@ -388,33 +388,33 @@ enum json_types
};
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
char *res, char *res_end);
} *json_service;
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp
index 7492642..b672db6 100644
--- a/include/mysql/plugin_password_validation.h.pp
+++ b/include/mysql/plugin_password_validation.h.pp
@@ -388,33 +388,33 @@ enum json_types
};
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
char *res, char *res_end);
} *json_service;
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/include/mysql/service_json.h b/include/mysql/service_json.h
index 2044172..734787a 100644
--- a/include/mysql/service_json.h
+++ b/include/mysql/service_json.h
@@ -61,17 +61,17 @@ enum json_types
extern struct json_service_st {
enum json_types (*json_type)(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_array_item)(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types (*json_get_object_key)(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types (*json_get_object_nkey)(const char *js,const char *js_end,
int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int (*json_escape_string)(const char *str,const char *str_end,
char *json, char *json_end);
int (*json_unescape_json)(const char *json_str, const char *json_end,
@@ -90,16 +90,16 @@ extern struct json_service_st {
#else
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen);
+ const char **value, int *value_len);
enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen);
+ const char *key, const char *key_end,
+ const char **value, int *value_len);
enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
const char **keyname, const char **keyname_end,
- const char **v, int *vlen);
+ const char **value, int *value_len);
int json_escape_string(const char *str,const char *str_end,
char *json, char *json_end);
int json_unescape_json(const char *json_str, const char *json_end,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b2840c3..61d6812 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1291,20 +1291,23 @@ class User_table_json: public User_table
return 0;
}
bool get_value(const char *key, size_t klen,
- enum json_value_types vt, const char **v, size_t *vl) const
+ enum json_types vt, const char **v, size_t *vl) const
{
- enum json_value_types value_type;
+ enum json_types value_type;
+ int int_vl;
String str, *res= m_table->field[2]->val_str(&str);
- if (!res || json_get_object_by_key(res->ptr(), res->length(), key, klen,
- &value_type, v, vl))
+ if (!res ||
+ (value_type= json_get_object_key(res->ptr(), res->end(),
+ key, key+klen, v, &int_vl)) == JSV_BAD_JSON)
return 1; // invalid
+ *vl= int_vl;
return value_type != vt;
}
const char *get_str_value(MEM_ROOT *root, const char *key, size_t klen) const
{
size_t value_len;
const char *value_start;
- if (get_value(key, klen, JSON_VALUE_STRING, &value_start, &value_len))
+ if (get_value(key, klen, JSV_STRING, &value_start, &value_len))
return "";
char *ptr= (char*)alloca(value_len);
int len= json_unescape(m_table->field[2]->charset(),
@@ -1321,7 +1324,7 @@ class User_table_json: public User_table
int err;
size_t value_len;
const char *value_start;
- if (get_value(key, klen, JSON_VALUE_NUMBER, &value_start, &value_len))
+ if (get_value(key, klen, JSV_NUMBER, &value_start, &value_len))
return 0;
const char *value_end= value_start + value_len;
return my_strtoll10(value_start, (char**)&value_end, &err);
@@ -1331,7 +1334,7 @@ class User_table_json: public User_table
int err;
size_t value_len;
const char *value_start;
- if (get_value(key, klen, JSON_VALUE_NUMBER, &value_start, &value_len))
+ if (get_value(key, klen, JSV_NUMBER, &value_start, &value_len))
return 0;
const char *value_end= value_start + value_len;
return my_strtod(value_start, (char**)&value_end, &err);
@@ -1340,25 +1343,26 @@ class User_table_json: public User_table
{
size_t value_len;
const char *value_start;
- if (get_value(key, klen, JSON_VALUE_TRUE, &value_start, &value_len))
+ if (get_value(key, klen, JSV_TRUE, &value_start, &value_len))
return false;
return true;
}
bool set_value(const char *key, size_t klen,
const char *val, size_t vlen, bool string) const
{
- size_t value_len;
+ int value_len;
const char *value_start;
- enum json_value_types value_type;
+ enum json_types value_type;
String str, *res= m_table->field[2]->val_str(&str);
if (!res || !res->length())
(res= &str)->set(STRING_WITH_LEN("{}"), m_table->field[2]->charset());
- if (json_get_object_by_key(res->ptr(), res->length(), key, klen,
- &value_type, &value_start, &value_len))
+ value_type= json_get_object_key(res->ptr(), res->end(), key, key+klen,
+ &value_start, &value_len);
+ if (value_type == JSV_BAD_JSON)
return 1; // invalid
StringBuffer<JSON_SIZE> json(res->charset());
json.copy(res->ptr(), value_start - res->ptr(), res->charset());
- if (!value_type)
+ if (value_type == JSV_NOTHING)
{
if (value_len)
json.append(',');
diff --git a/strings/json_lib.c b/strings/json_lib.c
index bc93601..8930581 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -1847,57 +1847,104 @@ int json_path_compare(const json_path_t *a, const json_path_t *b,
}
+static enum json_types smart_read_value(json_engine_t *je,
+ const char **value, int *value_len)
+{
+ if (json_read_value(je))
+ goto err_return;
+
+ *value= (char *) je->value;
+
+ if (json_value_scalar(je))
+ *value_len= je->value_len;
+ else
+ {
+ if (json_skip_level(je))
+ goto err_return;
+
+ *value_len= (char *) je->s.c_str - *value;
+ }
+
+ return je->value_type;
+
+err_return:
+ return JSV_BAD_JSON;
+}
+
+
enum json_types json_type(const char *js, const char *js_end,
- const char **v, int *vlen)
+ const char **value, int *value_len)
{
- return JSV_NOTHING;
+ json_engine_t je;
+
+ json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
+ (const uchar *) js_end);
+
+ return smart_read_value(&je, value, value_len);
}
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
- const char **v, int *vlen)
+ const char **value, int *value_len)
{
- return JSV_NOTHING;
-}
+ json_engine_t je;
+ int c_item= 0;
+ json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
+ (const uchar *) js_end);
-enum json_types json_get_object_key(const char *js, const char *js_end,
- const char *key,
- const char **v, int *vlen)
-{
- return JSV_NOTHING;
-}
+ if (json_read_value(&je) ||
+ je.value_type != JSON_VALUE_ARRAY)
+ goto err_return;
+ while (!json_scan_next(&je))
+ {
+ switch (je.state)
+ {
+ case JST_VALUE:
+ if (c_item == n_item)
+ return smart_read_value(&je, value, value_len);
-enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
- const char **keyname, const char **keyname_end,
- const char **v, int *vlen)
-{
- return JSV_NOTHING;
+ if (json_skip_key(&je))
+ goto err_return;
+
+ c_item++;
+ break;
+
+ case JST_ARRAY_END:
+ *value= (const char *) (je.s.c_str - je.sav_c_len);
+ *value_len= c_item;
+ return JSV_NOTHING;
+ }
+ }
+
+err_return:
+ return JSV_BAD_JSON;
}
+
/** Simple json lookup for a value by the key.
- Only supports flat json objects.
- Does not look inside nested objects.
- Does not process complex path expressions.
+ Expects JSON object.
+ Only scans the 'first level' of the object, not
+ the nested structures.
- @param js [in] json to search in
- @param js_len [in] - " -
+ @param js [in] json object to search in
+ @param js_end [in] end of json string
@param key [in] key to search for
- @param key_len [in] - " -
- @param value_type [out] type of the value found or 0 if not found
+ @param key_end [in] - " -
@param value_start [out] pointer into js (value or closing })
@param value_len [out] length of the value found or number of keys
- @retval 0 - success
- @retval 1 - error (invalid json)
+ @retval the type of the key value
+ @retval JSV_BAD_JSON - syntax error found reading JSON.
+ or not JSON object.
+ @retval JSV_NOTHING - no such key found.
*/
-int json_get_object_by_key(const char *js, size_t js_len,
- const char *key, size_t key_len,
- enum json_value_types *value_type,
- const char **value_start, size_t *value_len)
+enum json_types json_get_object_key(const char *js, const char *js_end,
+ const char *key, const char *key_end,
+ const char **value, int *value_len)
{
json_engine_t je;
json_string_t key_name;
@@ -1906,7 +1953,7 @@ int json_get_object_by_key(const char *js, size_t js_len,
json_string_set_cs(&key_name, &my_charset_utf8mb4_bin);
json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
- (const uchar *) js + js_len);
+ (const uchar *) js_end);
if (json_read_value(&je) ||
je.value_type != JSON_VALUE_OBJECT)
@@ -1919,35 +1966,35 @@ int json_get_object_by_key(const char *js, size_t js_len,
case JST_KEY:
n_keys++;
json_string_set_str(&key_name, (const uchar *) key,
- (const uchar *) key + key_len);
- if (!json_key_matches(&je, &key_name))
- {
- if (json_skip_key(&je))
- goto err_return;
- }
- else
- {
- if (json_read_value(&je))
- goto err_return;
- *value_type= je.value_type;
- *value_start= (const char *) je.value;
- *value_len= je.value_len;
- return 0;
- }
+ (const uchar *) key_end);
+ if (json_key_matches(&je, &key_name))
+ return smart_read_value(&je, value, value_len);
+
+ if (json_skip_key(&je))
+ goto err_return;
+
break;
case JST_OBJ_END:
- *value_type= (enum json_value_types) 0;
- *value_start= (const char *) (je.s.c_str - je.sav_c_len);
+ *value= (const char *) (je.s.c_str - je.sav_c_len);
*value_len= n_keys;
- return 0;
+ return JSV_NOTHING;
}
}
err_return:
- return 1;
+ return JSV_BAD_JSON;
}
+
+enum json_types json_get_object_nkey(const char *js,const char *js_end, int nkey,
+ const char **keyname, const char **keyname_end,
+ const char **value, int *value_len)
+{
+ return JSV_NOTHING;
+}
+
+
/** Check if json is valid (well-formed)
@retval 0 - success, json is well-formed
diff --git a/unittest/strings/CMakeLists.txt b/unittest/strings/CMakeLists.txt
index 2457475..0896e13 100644
--- a/unittest/strings/CMakeLists.txt
+++ b/unittest/strings/CMakeLists.txt
@@ -1,3 +1,3 @@
-MY_ADD_TESTS(strings LINK_LIBRARIES strings mysys)
+MY_ADD_TESTS(strings json LINK_LIBRARIES strings mysys)
1
0
16 Jan '19
revision-id: b9d74b760e6196a5f57ec76164f34ccfd677ba68 (mariadb-10.3.6-306-gb9d74b760e6)
parent(s): 203bb87d27be66787ff1972c0261902881a8580c
author: Jan Lindström
committer: Jan Lindström
timestamp: 2019-01-16 15:16:23 +0200
message:
MDEV-17705: Review InnoDB changes on Galera 4 wsrep patch
mysql-test/include/check-testcase.test
Reset innodb_status_output and innodb_status_output_locks variables
back to original values. This fixes test failure seen sometimes
on galera.galera_many_rows.
Test cleanups:
modified: mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
modified: mysql-test/suite/galera/r/galera_ist_progress.result
modified: mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
modified: mysql-test/suite/galera/r/galera_sst_rsync,debug.rdiff
modified: mysql-test/suite/galera/r/galera_toi_ddl_fk_insert.result
modified: mysql-test/suite/galera/r/galera_var_slave_threads.result
modified: mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result
modified: mysql-test/suite/galera/t/galera_bf_abort_group_commit.test
modified: mysql-test/suite/galera/t/galera_parallel_autoinc_largetrx.test
modified: mysql-test/suite/galera/t/galera_sst_mysqldump.test
modified: mysql-test/suite/galera/t/galera_toi_ddl_locking.test
modified: mysql-test/suite/galera/t/galera_var_slave_threads.test
modified: mysql-test/suite/galera/t/rpl_row_annotate.test
Remove xtrabackup related tests:
deleted: mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result
deleted: mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result
deleted: mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
deleted: mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf
deleted: mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test
wsrep_append_foreign_key
Fix output formating
row_ins_check_foreign_constraint
Revert unneeded change
row_search_mvcc
Use else to avoid performance penalty
trx_get_trx_by_xid_callback
Revert incorrect merge.
---
mysql-test/include/check-testcase.test | 8 +-
.../r/galera_gcache_recover_full_gcache.result | 2 +
.../suite/galera/r/galera_ist_progress.result | 14 -
.../r/galera_parallel_autoinc_largetrx.result | 18 +-
.../suite/galera/r/galera_sst_rsync,debug.rdiff | 6 +-
.../suite/galera/r/galera_toi_ddl_fk_insert.result | 2 +
.../suite/galera/r/galera_var_slave_threads.result | 425 ++++++++++++++++++++-
.../r/galera_wsrep_provider_unset_set.result | 2 +
.../galera/t/galera_bf_abort_group_commit.test | 23 +-
.../galera/t/galera_parallel_autoinc_largetrx.test | 11 +-
.../suite/galera/t/galera_sst_mysqldump.test | 1 -
.../suite/galera/t/galera_toi_ddl_locking.test | 2 +-
.../suite/galera/t/galera_var_slave_threads.test | 20 +-
mysql-test/suite/galera/t/rpl_row_annotate.test | 1 -
.../r/galera_innobackupex_backup.result | 11 -
.../r/galera_ipv6_xtrabackup-v2.result | 15 -
.../t/galera_innobackupex_backup.test | 58 ---
.../galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf | 30 --
.../galera_3nodes/t/galera_ipv6_xtrabackup-v2.test | 64 ----
storage/innobase/handler/ha_innodb.cc | 8 +-
storage/innobase/row/row0ins.cc | 21 +-
storage/innobase/row/row0sel.cc | 2 +-
storage/innobase/trx/trx0trx.cc | 7 -
23 files changed, 480 insertions(+), 271 deletions(-)
diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test
index 994b71f1ff6..39aa3d49d68 100644
--- a/mysql-test/include/check-testcase.test
+++ b/mysql-test/include/check-testcase.test
@@ -118,11 +118,15 @@ if (`SELECT COUNT(*)=1 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'wsre
}
--echo There is one or more active InnoDB transaction(s) when there should be none. Dumping some diagnostics.
+ --let $status_locks = `SELECT @@innodb_status_output_locks`
+ --let $status_output = `SELECT @@innodb_status_output`
--enable_query_log
-
SET GLOBAL innodb_status_output_locks=ON;
SHOW ENGINE INNODB STATUS;
- SET GLOBAL innodb_status_output_locks=default;
+ --disable_query_log
+ --eval SET GLOBAL innodb_status_output_locks=$status_locks;
+ --eval SET GLOBAL innodb_status_output=$status_output;
+ --enable_query_log
--vertical_results
if ($before) {
diff --git a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
index 157b982940b..a0d128f5fa3 100644
--- a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
+++ b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
@@ -1,3 +1,5 @@
+connection node_2;
+connection node_1;
SET SESSION wsrep_sync_wait = 0;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 LONGBLOB) ENGINE=InnoDB;
connection node_2;
diff --git a/mysql-test/suite/galera/r/galera_ist_progress.result b/mysql-test/suite/galera/r/galera_ist_progress.result
index 4795fc1224b..9fc7febbea5 100644
--- a/mysql-test/suite/galera/r/galera_ist_progress.result
+++ b/mysql-test/suite/galera/r/galera_ist_progress.result
@@ -1,15 +1,6 @@
-connection node_2;
-<<<<<<< HEAD
-connection node_1;
-connection node_2;
-=======
->>>>>>> 10.3
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 1';
-connection node_1;
-connection node_2;
SET SESSION wsrep_on = OFF;
SET SESSION wsrep_on = ON;
-connection node_1;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (2);
@@ -21,13 +12,8 @@ INSERT INTO t1 VALUES (7);
INSERT INTO t1 VALUES (8);
INSERT INTO t1 VALUES (9);
INSERT INTO t1 VALUES (10);
-connection node_2;
SET GLOBAL wsrep_provider_options = 'gmcast.isolate = 0';
-connection node_1;
-connection node_2;
-connection node_1;
include/assert_grep.inc [Receiving IST: 11 writesets, seqnos]
include/assert_grep.inc [Receiving IST\.\.\. 0\.0% \( 0/11 events\) complete]
include/assert_grep.inc [Receiving IST\.\.\.100\.0% \(11/11 events\) complete]
-connection node_1;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result b/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
index 85f61cc2742..d2e09d7084f 100644
--- a/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
+++ b/mysql-test/suite/galera/r/galera_parallel_autoinc_largetrx.result
@@ -1,7 +1,7 @@
connection node_2;
connection node_1;
connection node_1;
-CREATE TABLE ten (f1 INTEGER);
+CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
connection node_2;
@@ -13,18 +13,26 @@ INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;;
connection node_2;
INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;;
connection node_1;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+30000
+SELECT COUNT(DISTINCT f1) FROM t1;
+COUNT(DISTINCT f1)
+30000
connection node_1a;
-connection node_2;
SELECT COUNT(*) FROM t1;
COUNT(*)
30000
SELECT COUNT(DISTINCT f1) FROM t1;
COUNT(DISTINCT f1)
30000
-SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE
-USER = 'system user' AND STATE NOT LIKE 'InnoDB%';
+connection node_2;
+SELECT COUNT(*) FROM t1;
COUNT(*)
-6
+30000
+SELECT COUNT(DISTINCT f1) FROM t1;
+COUNT(DISTINCT f1)
+30000
connection default;
DROP TABLE t1;
DROP TABLE ten;
diff --git a/mysql-test/suite/galera/r/galera_sst_rsync,debug.rdiff b/mysql-test/suite/galera/r/galera_sst_rsync,debug.rdiff
index 3a6638c8cdb..94dd8c2e502 100644
--- a/mysql-test/suite/galera/r/galera_sst_rsync,debug.rdiff
+++ b/mysql-test/suite/galera/r/galera_sst_rsync,debug.rdiff
@@ -1,6 +1,6 @@
---- galera_sst_rsync.result 2018-12-11 13:47:33.600535840 +0100
-+++ galera_sst_rsync.reject 2018-12-11 13:52:05.780535840 +0100
-@@ -288,3 +288,111 @@
+--- galera_sst_rsync.result
++++ galera_sst_rsync,debug.reject
+@@ -284,3 +284,111 @@
DROP TABLE t1;
COMMIT;
SET AUTOCOMMIT=ON;
diff --git a/mysql-test/suite/galera/r/galera_toi_ddl_fk_insert.result b/mysql-test/suite/galera/r/galera_toi_ddl_fk_insert.result
index 0dbc89978d4..0ecc4a4619f 100644
--- a/mysql-test/suite/galera/r/galera_toi_ddl_fk_insert.result
+++ b/mysql-test/suite/galera/r/galera_toi_ddl_fk_insert.result
@@ -1,3 +1,5 @@
+connection node_2;
+connection node_1;
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE parent (
diff --git a/mysql-test/suite/galera/r/galera_var_slave_threads.result b/mysql-test/suite/galera/r/galera_var_slave_threads.result
index ca4b2b00bdf..108908551f6 100644
--- a/mysql-test/suite/galera/r/galera_var_slave_threads.result
+++ b/mysql-test/suite/galera/r/galera_var_slave_threads.result
@@ -17,11 +17,11 @@ SELECT @@wsrep_slave_threads = 1;
@@wsrep_slave_threads = 1
1
SET GLOBAL wsrep_slave_threads = 1;
-SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
-COUNT(*) = 3
-1
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
-COUNT(*) = 1
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
+COUNT(*)
+3
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+COUNT(*)
1
SET GLOBAL wsrep_slave_threads = 64;
connection node_1;
@@ -30,17 +30,17 @@ connection node_2;
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
1
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
-COUNT(*) = 1
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+COUNT(*)
1
SET GLOBAL wsrep_slave_threads = 1;
connection node_1;
connection node_2;
-SELECT COUNT(*) = 64 FROM t2;
-COUNT(*) = 64
-1
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
-COUNT(*) = 1
+SELECT COUNT(*) FROM t2;
+COUNT(*)
+64
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+COUNT(*)
1
SET GLOBAL wsrep_slave_threads = 5;
SET GLOBAL wsrep_slave_threads = 1;
@@ -56,15 +56,410 @@ SET GLOBAL wsrep_cluster_address='';
SET GLOBAL wsrep_cluster_address='gcomm://';
SET GLOBAL wsrep_slave_threads = 10;
connection node_2;
-SELECT COUNT(*) = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
-COUNT(*) = @@wsrep_slave_threads + 2
-1
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
+COUNT(*)
+3
connection node_1;
SET GLOBAL wsrep_slave_threads = 1;
connection node_2;
SET GLOBAL wsrep_slave_threads = 1;
connection node_1;
connection node_2;
+SELECT * FROM t1;
+f1
+1
+SELECT * FROM t2;
+f1
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+23
+25
+27
+29
+31
+33
+35
+37
+39
+41
+43
+45
+47
+49
+51
+53
+55
+57
+59
+61
+63
+65
+67
+69
+71
+73
+75
+77
+79
+81
+83
+85
+87
+89
+91
+93
+95
+97
+99
+101
+103
+105
+107
+109
+111
+113
+115
+117
+119
+121
+123
+125
+127
+129
+132
+134
+136
+138
+140
+142
+144
+146
+148
+150
+152
+154
+156
+158
+160
+162
+164
+166
+168
+170
+172
+174
+176
+178
+180
+182
+184
+186
+188
+190
+192
+194
+196
+198
+200
+202
+204
+206
+208
+210
+212
+214
+216
+218
+220
+222
+224
+226
+228
+230
+232
+234
+236
+238
+240
+242
+244
+246
+248
+250
+252
+254
+256
+258
+259
+261
+263
+265
+267
+269
+271
+273
+275
+277
+279
+281
+283
+285
+287
+289
+291
+293
+295
+297
+299
+301
+303
+305
+307
+309
+311
+313
+315
+317
+319
+321
+323
+325
+327
+329
+331
+333
+335
+337
+339
+341
+343
+345
+347
+349
+351
+353
+355
+357
+359
+361
+363
+365
+367
+369
+371
+373
+375
+377
+379
+381
+383
+385
+connection node_1;
+SELECT * FROM t1;
+f1
+1
+SELECT * FROM t2;
+f1
+3
+5
+7
+9
+11
+13
+15
+17
+19
+21
+23
+25
+27
+29
+31
+33
+35
+37
+39
+41
+43
+45
+47
+49
+51
+53
+55
+57
+59
+61
+63
+65
+67
+69
+71
+73
+75
+77
+79
+81
+83
+85
+87
+89
+91
+93
+95
+97
+99
+101
+103
+105
+107
+109
+111
+113
+115
+117
+119
+121
+123
+125
+127
+129
+132
+134
+136
+138
+140
+142
+144
+146
+148
+150
+152
+154
+156
+158
+160
+162
+164
+166
+168
+170
+172
+174
+176
+178
+180
+182
+184
+186
+188
+190
+192
+194
+196
+198
+200
+202
+204
+206
+208
+210
+212
+214
+216
+218
+220
+222
+224
+226
+228
+230
+232
+234
+236
+238
+240
+242
+244
+246
+248
+250
+252
+254
+256
+258
+259
+261
+263
+265
+267
+269
+271
+273
+275
+277
+279
+281
+283
+285
+287
+289
+291
+293
+295
+297
+299
+301
+303
+305
+307
+309
+311
+313
+315
+317
+319
+321
+323
+325
+327
+329
+331
+333
+335
+337
+339
+341
+343
+345
+347
+349
+351
+353
+355
+357
+359
+361
+363
+365
+367
+369
+371
+373
+375
+377
+379
+381
+383
+385
DROP TABLE t1;
DROP TABLE t2;
# End of tests
diff --git a/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result b/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result
index d56d9340474..7a645407004 100644
--- a/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result
+++ b/mysql-test/suite/galera/r/galera_wsrep_provider_unset_set.result
@@ -1,3 +1,5 @@
+connection node_2;
+connection node_1;
connection node_1;
connection node_2;
connection node_1;
diff --git a/mysql-test/suite/galera/t/galera_bf_abort_group_commit.test b/mysql-test/suite/galera/t/galera_bf_abort_group_commit.test
index 255298565f0..a828701cd0e 100644
--- a/mysql-test/suite/galera/t/galera_bf_abort_group_commit.test
+++ b/mysql-test/suite/galera/t/galera_bf_abort_group_commit.test
@@ -5,6 +5,7 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
+--source include/galera_have_debug_sync.inc
# Control connection for manipulating sync points on node 1
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
@@ -17,19 +18,19 @@ SET SESSION wsrep_sync_wait = 0;
--echo after_replicate_sync
--let $galera_sr_bf_abort_sync_point = after_replicate_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo local_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = local_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo apply_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = apply_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo commit_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = commit_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
# SR bf abort on commit fragment
--let $wsrep_trx_fragment_size = 1
@@ -38,15 +39,15 @@ SET SESSION wsrep_sync_wait = 0;
--echo after_replicate_sync
--let $galera_sr_bf_abort_sync_point = after_replicate_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo local_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = local_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo apply_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = apply_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo commit_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = commit_monitor_master_enter_sync
@@ -59,18 +60,18 @@ SET SESSION wsrep_sync_wait = 0;
--echo after_replicate_sync
--let $galera_sr_bf_abort_sync_point = after_replicate_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo local_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = local_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo apply_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = apply_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
--echo commit_monitor_master_enter_sync
--let $galera_sr_bf_abort_sync_point = commit_monitor_master_enter_sync
---source suite/galera/t/galera_sr_bf_abort.inc
+--source ../../suite/galera_sr/t/galera_sr_bf_abort.inc
CALL mtr.add_suppression("WSREP: fragment replication failed: 1");
diff --git a/mysql-test/suite/galera/t/galera_parallel_autoinc_largetrx.test b/mysql-test/suite/galera/t/galera_parallel_autoinc_largetrx.test
index 644b4687cb3..203d18b85a6 100644
--- a/mysql-test/suite/galera/t/galera_parallel_autoinc_largetrx.test
+++ b/mysql-test/suite/galera/t/galera_parallel_autoinc_largetrx.test
@@ -12,13 +12,16 @@
--source include/galera_connect.inc
--connection node_1
-CREATE TABLE ten (f1 INTEGER);
+CREATE TABLE ten (f1 INTEGER) engine=InnoDB;
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
CREATE TABLE t1 (f1 INTEGER AUTO_INCREMENT PRIMARY KEY, f2 INTEGER) Engine=InnoDB;
+
--connection node_2
--let $wsrep_slave_threads_orig = `SELECT @@wsrep_slave_threads`
SET GLOBAL wsrep_slave_threads = 4;
+--let $wait_condition = SELECT VARIABLE_VALUE = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
+--source include/wait_condition.inc
--connection node_1
--send INSERT INTO t1 (f2) SELECT 1 FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
@@ -31,16 +34,18 @@ SET GLOBAL wsrep_slave_threads = 4;
--connection node_1
--reap
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(DISTINCT f1) FROM t1;
--connection node_1a
--reap
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(DISTINCT f1) FROM t1;
--connection node_2
--reap
SELECT COUNT(*) FROM t1;
SELECT COUNT(DISTINCT f1) FROM t1;
-SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE
- USER = 'system user' AND STATE NOT LIKE 'InnoDB%';
--disable_query_log
--eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_threads_orig;
diff --git a/mysql-test/suite/galera/t/galera_sst_mysqldump.test b/mysql-test/suite/galera/t/galera_sst_mysqldump.test
index b72fa687411..cce4d374a6d 100644
--- a/mysql-test/suite/galera/t/galera_sst_mysqldump.test
+++ b/mysql-test/suite/galera/t/galera_sst_mysqldump.test
@@ -1,6 +1,5 @@
--source include/big_test.inc
--source include/galera_cluster.inc
---source include/have_innodb.inc
--source suite/galera/include/galera_sst_set_mysqldump.inc
--let $node_1=node_1
diff --git a/mysql-test/suite/galera/t/galera_toi_ddl_locking.test b/mysql-test/suite/galera/t/galera_toi_ddl_locking.test
index 08655157fd3..22a45316306 100644
--- a/mysql-test/suite/galera/t/galera_toi_ddl_locking.test
+++ b/mysql-test/suite/galera/t/galera_toi_ddl_locking.test
@@ -29,7 +29,7 @@ SET SESSION wsrep_sync_wait = 0;
SET DEBUG_SYNC= 'RESET';
SET DEBUG_SYNC = 'alter_table_before_open_tables SIGNAL before_open_tables WAIT_FOR continue';
--send ALTER TABLE t1 ADD COLUMN f2 INTEGER;
---sleep 10
+
--connection node_1a
SET DEBUG_SYNC= 'now WAIT_FOR before_open_tables';
diff --git a/mysql-test/suite/galera/t/galera_var_slave_threads.test b/mysql-test/suite/galera/t/galera_var_slave_threads.test
index 86c223b3a6c..d0784bfd871 100644
--- a/mysql-test/suite/galera/t/galera_var_slave_threads.test
+++ b/mysql-test/suite/galera/t/galera_var_slave_threads.test
@@ -26,8 +26,8 @@ SELECT @@wsrep_slave_threads = 1;
SET GLOBAL wsrep_slave_threads = 1;
# There is a separate wsrep_aborter thread at all times
-SELECT COUNT(*) = 3 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
#
# Increase the number of slave threads. The change takes effect immediately
@@ -45,7 +45,7 @@ SELECT COUNT(*) = 1 FROM t1;
# note, in wsrep API #26, we have 2 rollbacker threads, counted as system user's
#
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
--let $wait_condition = SELECT VARIABLE_VALUE = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
--source include/wait_condition.inc
@@ -71,9 +71,9 @@ while ($count)
--enable_result_log
--connection node_2
-SELECT COUNT(*) = 64 FROM t2;
+SELECT COUNT(*) FROM t2;
-SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND STATE LIKE '%wsrep aborter%';
--let $wait_condition = SELECT VARIABLE_VALUE = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
--source include/wait_condition.inc
@@ -131,7 +131,7 @@ SET GLOBAL wsrep_slave_threads = 10;
--source include/start_mysqld.inc
--source include/wait_until_connected_again.inc
-SELECT COUNT(*) = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER = 'system user' AND COMMAND != 'Daemon';
#
#
@@ -177,6 +177,14 @@ while ($count)
--let $wait_condition = SELECT VARIABLE_VALUE = @@wsrep_slave_threads + 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_thread_count';
--source include/wait_condition.inc
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+--connection node_1
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
DROP TABLE t1;
DROP TABLE t2;
diff --git a/mysql-test/suite/galera/t/rpl_row_annotate.test b/mysql-test/suite/galera/t/rpl_row_annotate.test
index b9bae724d7f..0ec30829982 100644
--- a/mysql-test/suite/galera/t/rpl_row_annotate.test
+++ b/mysql-test/suite/galera/t/rpl_row_annotate.test
@@ -42,5 +42,4 @@ let $start_pos= `select @binlog_start_pos`;
# Cleanup
DROP TABLE t1;
-#--source include/galera_end.inc
--echo # End of test
diff --git a/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result b/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result
deleted file mode 100644
index 85000db8e77..00000000000
--- a/mysql-test/suite/galera_3nodes/r/galera_innobackupex_backup.result
+++ /dev/null
@@ -1,11 +0,0 @@
-CREATE TABLE t1 (f1 INTEGER);
-INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
-SELECT COUNT(*) = 10 FROM t1;
-COUNT(*) = 10
-1
-Killing server ...
-INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
-SELECT COUNT(*) = 20 FROM t1;
-COUNT(*) = 20
-1
-DROP TABLE t1;
diff --git a/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result b/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result
deleted file mode 100644
index 56348889cf9..00000000000
--- a/mysql-test/suite/galera_3nodes/r/galera_ipv6_xtrabackup-v2.result
+++ /dev/null
@@ -1,15 +0,0 @@
-SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
-VARIABLE_VALUE LIKE '%[::1]%'
-1
-SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
-VARIABLE_VALUE = 3
-1
-SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
-CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1);
-SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
-SELECT COUNT(*) = 1 FROM t1;
-COUNT(*) = 1
-1
-DROP TABLE t1;
-include/assert_grep.inc [Streaming the backup to joiner at \[::1\]]
diff --git a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test b/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
deleted file mode 100644
index cc3f42c7290..00000000000
--- a/mysql-test/suite/galera_3nodes/t/galera_innobackupex_backup.test
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# This test uses innobackupex to take a backup on node #2 and then restores that node from backup
-#
-
---source include/galera_cluster.inc
---source include/have_innodb.inc
-
---connection node_1
-CREATE TABLE t1 (f1 INTEGER);
-INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
-
---connection node_2
-SELECT COUNT(*) = 10 FROM t1;
-
---exec rm -rf $MYSQL_TMP_DIR/innobackupex_backup
---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-backup.log
---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 $MYSQL_TMP_DIR/innobackupex_backup --apply-log --galera-info --port=$NODE_MYPORT_2 --host=127.0.0.1 --no-timestamp > $MYSQL_TMP_DIR/innobackupex-apply.log
-
---source ../galera/include/kill_galera.inc
---sleep 1
-
---connection node_1
-INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
-
---exec rm -rf $MYSQLTEST_VARDIR/mysqld.2/data/*
---exec innobackupex --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group=mysqld.2 --copy-back $MYSQL_TMP_DIR/innobackupex_backup --port=$NODE_MYPORT_2 --host=127.0.0.1 > $MYSQL_TMP_DIR/innobackupex-restore.log
-
-#
-# Convert the xtrabackup_galera_info into a grastate.dat file
-#
-
---perl
- use strict;
- my $xtrabackup_galera_info_file = $ENV{'MYSQL_TMP_DIR'}.'/innobackupex_backup/xtrabackup_galera_info';
- open(XTRABACKUP_GALERA_INFO, $xtrabackup_galera_info_file) or die "Can not open $xtrabackup_galera_info_file: $!";
- my $xtrabackup_galera_info = <XTRABACKUP_GALERA_INFO>;
- my ($uuid, $seqno) = split(':', $xtrabackup_galera_info);
-
- my $grastate_dat_file = $ENV{'MYSQLTEST_VARDIR'}.'/mysqld.2/data/grastate.dat';
- die "grastate.dat already exists" if -e $grastate_dat_file;
-
- open(GRASTATE_DAT, ">$grastate_dat_file") or die "Can not write to $grastate_dat_file: $!";
- print GRASTATE_DAT "version: 2.1\n";
- print GRASTATE_DAT "uuid: $uuid\n";
- print GRASTATE_DAT "seqno: $seqno\n";
- print GRASTATE_DAT "cert_index:\n";
- exit(0);
-EOF
-
---source include/start_mysqld.inc
---sleep 5
-
---source include/wait_until_connected_again.inc
-SELECT COUNT(*) = 20 FROM t1;
-
-DROP TABLE t1;
-
---sleep 10
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf
deleted file mode 100644
index 5cc8fb04cdd..00000000000
--- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.cnf
+++ /dev/null
@@ -1,30 +0,0 @@
-!include ../galera_3nodes.cnf
-
-[mysqld]
-wsrep_sst_method=xtrabackup-v2
-wsrep_sst_auth="root:"
-
-[mysqld.1]
-wsrep_node_name='node_1'
-wsrep-cluster-address=gcomm://
-wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port'
-wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port'
-wsrep_node_incoming_address='[::1]:@mysqld.1.port'
-
-[mysqld.2]
-wsrep_node_name='node_2'
-wsrep_sst_donor='node_1'
-wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
-wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port'
-wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port'
-wsrep_node_incoming_address='[::1]:@mysqld.2.port'
-
-[mysqld.3]
-wsrep_node_name='node_3'
-wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
-wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port'
-wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
-wsrep_node_incoming_address='[::1]:@mysqld.3.port'
-
-[SST]
-sockopt=",pf=ip6"
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test b/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test
deleted file mode 100644
index aa8635efad2..00000000000
--- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_xtrabackup-v2.test
+++ /dev/null
@@ -1,64 +0,0 @@
---source include/galera_cluster.inc
---source include/check_ipv6.inc
-
-# Confirm that initial handshake happened over ipv6
-
-SELECT VARIABLE_VALUE LIKE '%[::1]%' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';
-SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
-
-# Force IST
-
---connection node_2
-SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
-
---connection node_1
---let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
---source include/wait_condition.inc
-
-CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
-INSERT INTO t1 VALUES (1);
-
---connection node_2
-SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
-
---let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
---source include/wait_condition.inc
-
---let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
---source include/wait_condition.inc
-
-SELECT COUNT(*) = 1 FROM t1;
-
-DROP TABLE t1;
-
-# Confirm that key messages around SST and IST reference IPv6
-
---connection node_1
---let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
---let $assert_only_after = CURRENT_TEST
-
---let $assert_count = 2
---let $assert_text = Streaming the backup to joiner at \[::1\]
---let $assert_select = Streaming the backup to joiner at \[::1\]
---source include/assert_grep.inc
-
-# asserts below are not deterministic
-# --let $assert_count = 2
-# --let $assert_text = async IST sender starting to serve tcp://\[::1\]:
-# --let $assert_select = async IST sender starting to serve tcp://\[::1\]:
-# --source include/assert_grep.inc
-#
-# --let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
-#
-# --let $assert_text = IST receiver addr using tcp://\[::1\]
-# --let $assert_select = IST receiver addr using tcp://\[::1\]
-# --source include/assert_grep.inc
-#
-# --let $assert_count = 1
-# --let $assert_text = Prepared IST receiver for 4-7, listening at: tcp://\[::1\]
-# --let $assert_select = Prepared IST receiver for 4-7, listening at: tcp://\[::1\]
-# --source include/assert_grep.inc
-
-
-
-
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index e9f2c5b0754..8eb748e7a70 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -10282,11 +10282,11 @@ wsrep_append_foreign_key(
if (rcode != DB_SUCCESS) {
WSREP_ERROR(
- "FK key set failed: %lu (%lu %s), index: %s %s, %s",
+ "FK key set failed: " ULINTPF
+ " (" ULINTPF " " ULINTPF "%s), index: %s %s, %s",
rcode, referenced, wsrep_key_type_to_str(key_type),
- (index && index->name) ? index->name :
- "void index",
- (index) ? index->table->name.m_name :
+ (index) ? index->name() : "void index",
+ (index && index->table) ? index->table->name.m_name :
"void table",
wsrep_thd_query(thd));
return DB_ERROR;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index db4dd0759d0..c38e5813a6c 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1814,8 +1814,8 @@ row_ins_check_foreign_constraint(
rec,
check_index,
check_ref,
- upd_node != NULL &&
- wsrep_protocol_version < 4
+ (upd_node != NULL
+ && wsrep_protocol_version < 4)
? WSREP_SERVICE_KEY_SHARED
: WSREP_SERVICE_KEY_REFERENCE);
#endif /* WITH_WSREP */
@@ -1915,23 +1915,6 @@ row_ins_check_foreign_constraint(
check_table->inc_fk_checks();
lock_wait_suspend_thread(thr);
-#ifdef WITH_WSREP
- ut_ad(!trx_mutex_own(trx));
- switch (trx->error_state) {
- case DB_DEADLOCK:
- if (wsrep_debug) {
- ib::info() <<
- "WSREP: innodb trx state changed during wait "
- << " trx: " << trx->id << " with error_state: "
- << trx->error_state << " err: " << err;
- }
- err = trx->error_state;
- break;
- default:
- break;
- }
-
-#endif /* WITH_WSREP */
thr->lock_state = QUE_THR_LOCK_NOLOCK;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 80d84756724..f05d51da905 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -4467,7 +4467,7 @@ row_search_mvcc(
set_also_gap_locks = FALSE;
}
#ifdef WITH_WSREP
- if (wsrep_thd_skip_locking(trx->mysql_thd)) {
+ else if (wsrep_thd_skip_locking(trx->mysql_thd)) {
ut_ad(sr_table_name_full_str == prebuilt->table->name.m_name);
set_also_gap_locks = FALSE;
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 3873ed34bd5..d222e3f017c 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -2154,14 +2154,7 @@ static my_bool trx_get_trx_by_xid_callback(rw_trx_hash_element_t *element,
if (!wsrep_is_wsrep_xid(trx->xid))
#endif
/* Invalidate the XID, so that subsequent calls will not find it. */
-#ifdef WITH_WSREP
- if (!wsrep_is_wsrep_xid(trx->xid))
- {
-#endif /* WITH_WSREP */
trx->xid->null();
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
arg->trx= trx;
found= 1;
}
1
0
[Commits] a59d600cbaf: MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
by Oleksandr Byelkin 16 Jan '19
by Oleksandr Byelkin 16 Jan '19
16 Jan '19
revision-id: a59d600cbafd34e230da321b4a16339f5cf6976d (mariadb-5.5.62-18-ga59d600cbaf)
parent(s): dc42b3c4d9546153e2f0049393e3771e21551679
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2019-01-16 13:52:07 +0100
message:
MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
The problem was in calculating of the mask to clear unused null bits in case of using full byte.
---
mysql-test/r/row-checksum-old.result | 16 ++++++++++++++++
mysql-test/r/row-checksum.result | 16 ++++++++++++++++
mysql-test/t/row-checksum.test | 17 +++++++++++++++++
sql/sql_table.cc | 5 ++++-
4 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/row-checksum-old.result b/mysql-test/r/row-checksum-old.result
index ef523463860..920c5dbe838 100644
--- a/mysql-test/r/row-checksum-old.result
+++ b/mysql-test/r/row-checksum-old.result
@@ -85,3 +85,19 @@ checksum table t1 extended;
Table Checksum
test.t1 4108368782
drop table t1;
+#
+# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+#
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+# Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2514025256
+UPDATE t1 SET c21='cat' WHERE c1=5;
+# Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2326430205
+drop table t1;
+# End of 5.5 tests
diff --git a/mysql-test/r/row-checksum.result b/mysql-test/r/row-checksum.result
index fb8a1260a1d..0f8311b703a 100644
--- a/mysql-test/r/row-checksum.result
+++ b/mysql-test/r/row-checksum.result
@@ -85,3 +85,19 @@ checksum table t1 extended;
Table Checksum
test.t1 3885665021
drop table t1;
+#
+# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+#
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+# Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2514025256
+UPDATE t1 SET c21='cat' WHERE c1=5;
+# Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2326430205
+drop table t1;
+# End of 5.5 tests
diff --git a/mysql-test/t/row-checksum.test b/mysql-test/t/row-checksum.test
index 920a2384aa8..6b79827d066 100644
--- a/mysql-test/t/row-checksum.test
+++ b/mysql-test/t/row-checksum.test
@@ -60,3 +60,20 @@ checksum table t1;
checksum table t1 quick;
checksum table t1 extended;
drop table t1;
+
+--echo #
+--echo # MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+--echo #
+
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+--echo # Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+UPDATE t1 SET c21='cat' WHERE c1=5;
+--echo # Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+
+drop table t1;
+
+--echo # End of 5.5 tests
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1b83b513c2d..d3448c167c4 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7844,7 +7844,10 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
{
/* calculating table's checksum */
ha_checksum crc= 0;
- uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
+ DBUG_ASSERT(t->s->last_null_bit_pos < 8);
+ uchar null_mask= (t->s->last_null_bit_pos ?
+ (256 - (1 << t->s->last_null_bit_pos)):
+ 0);
t->use_all_columns();
1
0
revision-id: 9e1c0ea3cdbc3d9d69831bfd1e998bc373706acb (mariadb-5.5.62-19-g9e1c0ea3cdb)
parent(s): a6dec71637631c34cd2462989959fcbe4e30604c
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2019-01-16 13:51:56 +0100
message:
add assert by Marko
---
sql/sql_table.cc | 1 +
1 file changed, 1 insertion(+)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 3fb678e3d74..d3448c167c4 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7844,6 +7844,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
{
/* calculating table's checksum */
ha_checksum crc= 0;
+ DBUG_ASSERT(t->s->last_null_bit_pos < 8);
uchar null_mask= (t->s->last_null_bit_pos ?
(256 - (1 << t->s->last_null_bit_pos)):
0);
1
0
[Commits] a6dec716376: MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
by Oleksandr Byelkin 16 Jan '19
by Oleksandr Byelkin 16 Jan '19
16 Jan '19
revision-id: a6dec71637631c34cd2462989959fcbe4e30604c (mariadb-5.5.62-18-ga6dec716376)
parent(s): dc42b3c4d9546153e2f0049393e3771e21551679
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2019-01-16 13:16:41 +0100
message:
MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
The problem was in calculating of the mask to clear unused null bits in case of using full byte.
---
mysql-test/r/row-checksum-old.result | 16 ++++++++++++++++
mysql-test/r/row-checksum.result | 16 ++++++++++++++++
mysql-test/t/row-checksum.test | 17 +++++++++++++++++
sql/sql_table.cc | 4 +++-
4 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/row-checksum-old.result b/mysql-test/r/row-checksum-old.result
index ef523463860..920c5dbe838 100644
--- a/mysql-test/r/row-checksum-old.result
+++ b/mysql-test/r/row-checksum-old.result
@@ -85,3 +85,19 @@ checksum table t1 extended;
Table Checksum
test.t1 4108368782
drop table t1;
+#
+# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+#
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+# Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2514025256
+UPDATE t1 SET c21='cat' WHERE c1=5;
+# Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2326430205
+drop table t1;
+# End of 5.5 tests
diff --git a/mysql-test/r/row-checksum.result b/mysql-test/r/row-checksum.result
index fb8a1260a1d..0f8311b703a 100644
--- a/mysql-test/r/row-checksum.result
+++ b/mysql-test/r/row-checksum.result
@@ -85,3 +85,19 @@ checksum table t1 extended;
Table Checksum
test.t1 3885665021
drop table t1;
+#
+# MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+#
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+# Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2514025256
+UPDATE t1 SET c21='cat' WHERE c1=5;
+# Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 2326430205
+drop table t1;
+# End of 5.5 tests
diff --git a/mysql-test/t/row-checksum.test b/mysql-test/t/row-checksum.test
index 920a2384aa8..6b79827d066 100644
--- a/mysql-test/t/row-checksum.test
+++ b/mysql-test/t/row-checksum.test
@@ -60,3 +60,20 @@ checksum table t1;
checksum table t1 quick;
checksum table t1 extended;
drop table t1;
+
+--echo #
+--echo # MDEV-17085: CHECKSUM TABLE EXTENDED does not work correctly
+--echo #
+
+CREATE TABLE t1 ( c1 int NOT NULL, c2 int NOT NULL, c4 varchar(20), c5 varchar(20), c6 varchar(20), c7 varchar(20), c8 varchar(20), c9 varchar(20), c10 varchar(20), c11 varchar(20), c12 varchar(20), c13 varchar(20), c14 varchar(20), c15 varchar(20), c16 varchar(20), c19 int NOT NULL, c20 int NOT NULL, c21 varchar(20), c22 VARCHAR(20), c23 varchar(20));
+
+insert into t1 values (5,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,"dog",NULL,NULL);
+--echo # Important is that checksum is different from following
+CHECKSUM TABLE t1 EXTENDED;
+UPDATE t1 SET c21='cat' WHERE c1=5;
+--echo # Important is that checksum is different from above
+CHECKSUM TABLE t1 EXTENDED;
+
+drop table t1;
+
+--echo # End of 5.5 tests
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1b83b513c2d..3fb678e3d74 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7844,7 +7844,9 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
{
/* calculating table's checksum */
ha_checksum crc= 0;
- uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
+ uchar null_mask= (t->s->last_null_bit_pos ?
+ (256 - (1 << t->s->last_null_bit_pos)):
+ 0);
t->use_all_columns();
1
0
[Commits] 203bb87d27b: Merge remote-tracking branch 'origin/10.4' into bb-10.4-galera4
by jan 16 Jan '19
by jan 16 Jan '19
16 Jan '19
revision-id: 203bb87d27be66787ff1972c0261902881a8580c (mariadb-10.3.6-305-g203bb87d27b)
parent(s): db6385e26019c12fd8027bff42b35eb9e8039ab7 b13d356af8d7766e143b90834f5b0d32aba8eff7
author: Jan Lindström
committer: Jan Lindström
timestamp: 2019-01-16 07:58:32 +0200
message:
Merge remote-tracking branch 'origin/10.4' into bb-10.4-galera4
.gitignore | 3 +
.travis.yml | 6 +-
README.md | 3 +-
appveyor.yml | 4 +-
extra/mariabackup/xtrabackup.cc | 34 +++---
mysql-test/main/backup_locks.result | 46 +++++++++
mysql-test/main/backup_locks.test | 50 +++++++++
mysql-test/main/backup_syntax.result | 2 +-
mysql-test/main/func_math.result | 7 ++
mysql-test/main/func_math.test | 8 ++
mysql-test/main/func_str.result | 12 +++
mysql-test/main/func_str.test | 16 +++
mysql-test/main/mysqld--help.result | 2 +-
mysql-test/main/type_timestamp.result | 12 +++
mysql-test/main/type_timestamp.test | 11 ++
mysql-test/suite/galera/disabled.def | 4 +-
.../r/galera_gcache_recover_full_gcache.result | 7 ++
.../r/galera_ist_innodb_flush_logs,release.rdiff | 114 +++++++++++++++++++++
mysql-test/suite/innodb/r/innodb-index.result | 16 +++
mysql-test/suite/innodb/t/innodb-index.test | 22 ++++
mysql-test/suite/innodb/t/recovery_shutdown.test | 6 ++
.../mariabackup/drop_table_during_backup.result | 5 +
.../mariabackup/drop_table_during_backup.test | 9 ++
.../suite/mariabackup/rename_during_backup.result | 9 ++
.../suite/mariabackup/rename_during_backup.test | 7 ++
mysql-test/suite/rpl/r/rpl_user.result | 11 ++
mysql-test/suite/rpl/t/rpl_user.test | 11 ++
.../sys_vars/r/sysvars_server_embedded.result | 4 +-
.../sys_vars/r/sysvars_server_notembedded.result | 4 +-
mysql-test/suite/versioning/r/online.result | 8 ++
mysql-test/suite/versioning/t/online.test | 11 ++
sql/backup.cc | 29 ++++++
sql/backup.h | 3 +
sql/item.h | 14 ---
sql/item_func.cc | 20 ++--
sql/item_subselect.cc | 4 +-
sql/mysqld.cc | 3 +-
sql/sql_acl.cc | 6 ++
sql/sql_class.cc | 3 +
sql/sql_class.h | 2 +-
sql/sql_cmd.h | 2 +-
sql/sql_delete.cc | 4 +-
sql/sql_lex.cc | 2 +-
sql/sql_lex.h | 7 +-
sql/sql_parse.cc | 12 +++
sql/sql_string.cc | 2 +-
sql/sql_type_int.h | 16 +++
sql/sql_yacc.yy | 24 ++++-
sql/sql_yacc_ora.yy | 24 ++++-
storage/connect/plugutil.cpp | 2 +-
storage/innobase/btr/btr0bulk.cc | 1 +
storage/innobase/buf/buf0flu.cc | 2 +-
storage/innobase/dict/dict0dict.cc | 42 +++-----
storage/innobase/handler/ha_innodb.cc | 45 ++++----
storage/innobase/handler/handler0alter.cc | 72 ++++++++-----
storage/innobase/include/dict0dict.h | 15 ---
storage/innobase/include/dict0dict.ic | 4 +-
storage/innobase/include/dict0mem.h | 7 ++
storage/innobase/include/fil0fil.h | 1 -
storage/innobase/include/log0log.h | 8 --
storage/innobase/log/log0log.cc | 16 +--
storage/innobase/trx/trx0trx.cc | 6 ++
storage/maria/test_ma_backup.c | 2 +-
63 files changed, 671 insertions(+), 193 deletions(-)
diff --cc mysql-test/suite/galera/disabled.def
index c9cb76126a5,7064df982dd..0b3ff4b42a0
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@@ -52,10 -50,5 +50,12 @@@ MW-328C : MDEV-17847 Galera test failur
galera.galera_encrypt_tmp_files : Get error failed to enable encryption of temporary files
galera.galera_var_reject_queries : assertion in inline_mysql_socket_send
query_cache : MDEV-18137: Galera test failure on query_cache
+ galera.galera_autoinc_sst_mariabackup : MDEV-18177 Galera test failure on galera_autoinc_sst_mariabackup
+ galera_gcache_recover_manytrx : MDEV-15740
+galera.galera_ist_mariabackup : Leaves port open
+galera.galera_autoinc_sst_mariabackup : MDEV-18177 Galera test failure on galera_autoinc_sst_mariabackup
+galera.galera_sst_rsync2 : MDEV-18178 Galera test failure on galera_sst_rsync2
+galera.galera_kill_largechanges : MDEV-18179 Galera test failure on galera.galera_kill_largechanges
+galera.galera_concurrent_ctas : MDEV-18180 Galera test failure on galera.galera_concurrent_ctas
+galera.galera_var_retry_autocommit: MDEV-18181 Galera test failure on galera.galera_var_retry_autocommit
+galera.galera_many_tables_nopk : MDEV-18182 Galera test failure on galera.galera_many_tables_nopk
diff --cc mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
index 45c426dfdf1,588af5668bb..157b982940b
--- a/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
+++ b/mysql-test/suite/galera/r/galera_gcache_recover_full_gcache.result
@@@ -8,12 -10,17 +10,17 @@@ INSERT INTO t1 (f2) VALUES (REPEAT('x'
INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10));
INSERT INTO t1 (f2) VALUES (REPEAT('x', 1024 * 1024 * 10));
Killing server ...
+ connection node_1;
Performing --wsrep-recover ...
Using --wsrep-start-position when starting mysqld ...
+ connection node_2;
Performing --wsrep-recover ...
Using --wsrep-start-position when starting mysqld ...
+ connection node_1;
include/diff_servers.inc [servers=1 2]
+ connection node_1;
DROP TABLE t1;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
-include/assert_grep.inc [IST first seqno 2 not found from cache, falling back to SST]
+include/assert_grep.inc [IST first seqno [24] not found from cache, falling back to SST]
+ connection node_2;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
diff --cc storage/innobase/trx/trx0trx.cc
index a3547ffca5b,333c7fe90eb..3873ed34bd5
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@@ -2147,15 -2150,14 +2147,21 @@@ static my_bool trx_get_trx_by_xid_callb
if (trx->is_recovered && trx_state_eq(trx, TRX_STATE_PREPARED) &&
arg->xid->eq(reinterpret_cast<XID*>(trx->xid)))
{
+ #ifdef WITH_WSREP
+ /* The commit of a prepared recovered Galera
+ transaction needs a valid trx->xid for
+ invoking trx_sys_update_wsrep_checkpoint(). */
+ if (!wsrep_is_wsrep_xid(trx->xid))
+ #endif
/* Invalidate the XID, so that subsequent calls will not find it. */
+#ifdef WITH_WSREP
+ if (!wsrep_is_wsrep_xid(trx->xid))
+ {
+#endif /* WITH_WSREP */
trx->xid->null();
+#ifdef WITH_WSREP
+ }
+#endif /* WITH_WSREP */
arg->trx= trx;
found= 1;
}
1
0
16 Jan '19
revision-id: db6385e26019c12fd8027bff42b35eb9e8039ab7 (mariadb-10.3.6-304-gdb6385e2601)
parent(s): b11b6458adf193be39d1463735d10e368feda9d6
author: Jan Lindström
committer: Jan Lindström
timestamp: 2019-01-16 07:57:11 +0200
message:
Enable galera_gcache_recover test and remove unnecessary
file.
---
mysql-test/suite/galera/disabled.def | 1 -
mysql-test/suite/galera/r/galera_gcache_recover.result | 9 +++++++++
mysql-test/suite/galera/t/disabled.def | 14 --------------
3 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 21f82473a0f..c9cb76126a5 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -20,7 +20,6 @@ galera_as_slave_preordered : wsrep-preordered feature not merged to MariaDB
GAL-419 : MDEV-13549 Galera test failures
galera_var_notify_cmd : MDEV-13549 Galera test failures
galera_as_slave_replication_bundle : MDEV-13549 Galera test failures
-galera_gcache_recover : MDEV-13549 Galera test failures
galera_gcache_recover_full_gcache : MDEV-13549 Galera test failures
galera_gcache_recover_manytrx : MDEV-13549 Galera test failures
galera_ssl_upgrade : MDEV-13549 Galera test failures
diff --git a/mysql-test/suite/galera/r/galera_gcache_recover.result b/mysql-test/suite/galera/r/galera_gcache_recover.result
index 127bcba39d8..819c595ece3 100644
--- a/mysql-test/suite/galera/r/galera_gcache_recover.result
+++ b/mysql-test/suite/galera/r/galera_gcache_recover.result
@@ -1,18 +1,27 @@
+connection node_2;
+connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
SET SESSION wsrep_sync_wait = 0;
+connection node_2;
SET SESSION wsrep_sync_wait = 0;
Killing server ...
+connection node_1;
INSERT INTO t1 VALUES (2);
Killing server ...
+connection node_1;
Performing --wsrep-recover ...
Using --wsrep-start-position when starting mysqld ...
INSERT INTO t1 VALUES (3);
+connection node_2;
Performing --wsrep-recover ...
Using --wsrep-start-position when starting mysqld ...
+connection node_1;
include/diff_servers.inc [servers=1 2]
+connection node_1;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
include/assert_grep.inc [async IST sender starting to serve]
+connection node_2;
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
include/assert_grep.inc [Recovering GCache ring buffer: found gapless sequence]
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/disabled.def b/mysql-test/suite/galera/t/disabled.def
deleted file mode 100644
index fc63e331023..00000000000
--- a/mysql-test/suite/galera/t/disabled.def
+++ /dev/null
@@ -1,14 +0,0 @@
-galera_wsrep_provider_unset_set : lp1379204 'Unsupported protocol downgrade: incremental data collection disabled. Expect abort.'
-galera_kill_nochanges : mysql-wsrep#24 Galera server does not restart properly if killed
-galera_toi_ddl_fk_insert : qa#39 galera_toi_ddl_fk_insert fails sporadically
-galera_sst_xtrabackup-v2-options : SST Encryption does not work with xtrabackup 2.4.2
-#galera_autoinc_sst_xtrabackup : due to cert index preload, this test will never pass in current form (gcache.size=1)
-GCF-574 : CTAS is not supported together with SR
-galera_split_brain : is worked on with tracker GCF-998
-galera_sr_kill_all_pcrecovery : is worked on with tracker GCF-1068
-galera_var_notify_cmd : is worked on with tracker GCF-1071
-galera_gcache_recover_manytrx : is worked on with tracker GCF-1077
-GCF-1081 : tries to BF abort earlier trx, needs to be reimplemented
-galera_bf_abort_group_commit : requires galera_sr_bf_abort.inc, probably needs reimplementation
-galera_as_slave_gtid_replicate_do_db_cc : assertion
-galera_autoinc_sst_xtrabackup : fails and reserves SST port until socat times out
1
0
[Commits] 69328c31ed3: MDEV-18176 Galera test failure on galera.galera_gtid_slave_sst_rsync
by jan 15 Jan '19
by jan 15 Jan '19
15 Jan '19
revision-id: 69328c31ed31048e5f60b9e8e5a21bbe3220f968 (mariadb-10.1.37-57-g69328c31ed3)
parent(s): 7d3161def8af04690e294d87d7483d3e0d54bbce
author: mkaruza
committer: Jan Lindström
timestamp: 2019-01-15 13:29:11 +0200
message:
MDEV-18176 Galera test failure on galera.galera_gtid_slave_sst_rsync
If galera.galera_gtid_slave_sst_rsync is repeated more than once it will fail due incorrect GTID position. After stopping SLAVE node reset also GTID_SLAVE_POS variable.
---
mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result | 1 +
mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test | 3 +++
2 files changed, 4 insertions(+)
diff --git a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
index 81fae57d731..7953910b385 100644
--- a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
+++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result
@@ -123,6 +123,7 @@ DROP TABLE t2,t1;
#Connection 2
STOP SLAVE;
RESET SLAVE ALL;
+set global gtid_slave_pos="";
reset master;
#Connection 3
reset master;
diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
index 3fe94ad16b7..3ed7ec1d09e 100644
--- a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
+++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test
@@ -196,6 +196,9 @@ DROP TABLE t2,t1;
--connection node_2
STOP SLAVE;
RESET SLAVE ALL;
+--disable_warnings
+set global gtid_slave_pos="";
+--enable_warnings
reset master;
--echo #Connection 3
1
0
[Commits] 971ad0c2d10: MDEV-16327 pre-requisits: isolation of LIMIT/OFFSET handling
by Oleksandr Byelkin 15 Jan '19
by Oleksandr Byelkin 15 Jan '19
15 Jan '19
revision-id: 971ad0c2d10ecb81f463acab0c03111f32634696 (mariadb-10.4.1-78-g971ad0c2d10)
parent(s): d97a26a67dca82d166e9edefe5f950ea8a110dfd
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2019-01-15 10:05:05 +0100
message:
MDEV-16327 pre-requisits: isolation of LIMIT/OFFSET handling
---
sql/group_by_handler.cc | 8 +++----
sql/group_by_handler.h | 1 +
sql/item_subselect.cc | 2 +-
sql/opt_subselect.cc | 9 +++-----
sql/sql_class.cc | 44 +++++++++++-------------------------
sql/sql_class.h | 6 ++---
sql/sql_derived.cc | 2 +-
sql/sql_error.cc | 10 ++++-----
sql/sql_insert.cc | 7 ++----
sql/sql_lex.cc | 10 ++-------
sql/sql_lex.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-
sql/sql_parse.cc | 13 ++++++-----
sql/sql_profile.cc | 10 ++++-----
sql/sql_repl.cc | 10 ++++-----
sql/sql_select.cc | 46 ++++++++++++++++++++------------------
sql/sql_union.cc | 36 +++++++++++++-----------------
16 files changed, 148 insertions(+), 125 deletions(-)
diff --git a/sql/group_by_handler.cc b/sql/group_by_handler.cc
index f18758a2d94..f5ed24370b1 100644
--- a/sql/group_by_handler.cc
+++ b/sql/group_by_handler.cc
@@ -40,7 +40,7 @@ int Pushdown_query::execute(JOIN *join)
{
int err;
ha_rows max_limit;
- ha_rows *reset_limit= 0;
+ bool reset_limit= FALSE;
Item **reset_item= 0;
THD *thd= handler->thd;
TABLE *table= handler->table;
@@ -52,11 +52,11 @@ int Pushdown_query::execute(JOIN *join)
if (store_data_in_temp_table)
{
max_limit= join->tmp_table_param.end_write_records;
- reset_limit= &join->unit->select_limit_cnt;
+ reset_limit= TRUE;
}
else
{
- max_limit= join->unit->select_limit_cnt;
+ max_limit= join->unit->lim.get_select_limit();
if (join->unit->fake_select_lex)
reset_item= &join->unit->fake_select_lex->select_limit;
}
@@ -112,7 +112,7 @@ int Pushdown_query::execute(JOIN *join)
break; // LIMIT reached
join->do_send_rows= 0; // Calculate FOUND_ROWS()
if (reset_limit)
- *reset_limit= HA_POS_ERROR;
+ join->unit->lim.set_unlimited();
if (reset_item)
*reset_item= 0;
}
diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h
index d3f48a15c24..be981f0da5f 100644
--- a/sql/group_by_handler.h
+++ b/sql/group_by_handler.h
@@ -56,6 +56,7 @@ struct Query
ORDER *order_by;
Item *having;
// LIMIT
+ //ha_rows select_limit_cnt, offset_limit_cnt;
};
class group_by_handler
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 0ace59fd2fc..e860c3fa98d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -2721,7 +2721,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
new (thd->mem_root)
Item_int(thd, (int32) 1));
- unit->select_limit_cnt= 1;
+ unit->lim.set_single_row();
DBUG_RETURN(false);
}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index c4c30c9b50d..e9284926385 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -5492,11 +5492,8 @@ int select_value_catcher::send_data(List<Item> &items)
DBUG_ASSERT(!assigned);
DBUG_ASSERT(items.elements == n_elements);
- if (unit->offset_limit_cnt)
- { // Using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // Using limit offset,count
Item *val_item;
List_iterator_fast<Item> li(items);
@@ -6289,7 +6286,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
Set the limit of this JOIN object as well, because normally its being
set in the beginning of JOIN::optimize, which was already done.
*/
- select_limit= in_subs->unit->select_limit_cnt;
+ select_limit= in_subs->unit->lim.get_select_limit();
}
else if (in_subs->test_strategy(SUBS_IN_TO_EXISTS))
{
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2952adbd3e6..ce6d71082fb 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2936,11 +2936,8 @@ int select_send::send_data(List<Item> &items)
DBUG_ENTER("select_send::send_data");
/* unit is not set when using 'delete ... returning' */
- if (unit && unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(FALSE);
- }
+ if (unit && unit->lim.check_and_move_offset())
+ DBUG_RETURN(FALSE); // using limit offset,count
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(FALSE);
@@ -3205,11 +3202,8 @@ int select_export::send_data(List<Item> &items)
String tmp(buff,sizeof(buff),&my_charset_bin),*res;
tmp.length(0);
- if (unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // using limit offset,count
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(0);
row_count++;
@@ -3465,11 +3459,8 @@ int select_dump::send_data(List<Item> &items)
Item *item;
DBUG_ENTER("select_dump::send_data");
- if (unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // using limit offset,count
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(0);
@@ -3508,11 +3499,8 @@ int select_singlerow_subselect::send_data(List<Item> &items)
MYF(current_thd->lex->ignore ? ME_WARNING : 0));
DBUG_RETURN(1);
}
- if (unit->offset_limit_cnt)
- { // Using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // Using limit offset,count
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(0);
List_iterator_fast<Item> li(items);
@@ -3649,11 +3637,8 @@ int select_exists_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_exists_subselect::send_data");
Item_exists_subselect *it= (Item_exists_subselect *)item;
- if (unit->offset_limit_cnt)
- { // Using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // Using limit offset,count
if (thd->killed == ABORT_QUERY)
DBUG_RETURN(0);
it->value= 1;
@@ -4060,12 +4045,9 @@ int select_dumpvar::send_data(List<Item> &items)
{
DBUG_ENTER("select_dumpvar::send_data");
- if (unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
- if (row_count++)
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // using limit offset,count
+ if (row_count++)
{
my_message(ER_TOO_MANY_ROWS, ER_THD(thd, ER_TOO_MANY_ROWS), MYF(0));
DBUG_RETURN(1);
diff --git a/sql/sql_class.h b/sql/sql_class.h
index b1da6e19247..7427b2745bc 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -5117,9 +5117,9 @@ class select_result :public select_result_sink
/* this method is called just before the first row of the table can be read */
virtual void prepare_to_read_rows() {}
- void reset_offset_limit()
+ void remove_offset_limit()
{
- unit->offset_limit_cnt= 0;
+ unit->lim.remove_offset();
}
/*
@@ -5786,7 +5786,7 @@ class select_union_direct :public select_unit
*/
DBUG_ASSERT(false); /* purecov: inspected */
}
- void reset_offset_limit_cnt()
+ void remove_offset_limit()
{
// EXPLAIN should never output to a select_union_direct
DBUG_ASSERT(false); /* purecov: inspected */
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 878aa715b84..4fd44a18550 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1148,7 +1148,7 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
{
SELECT_LEX *first_select= unit->first_select();
unit->set_limit(unit->global_parameters());
- if (unit->select_limit_cnt == HA_POS_ERROR)
+ if (unit->lim.is_unlimited())
first_select->options&= ~OPTION_FOUND_ROWS;
lex->current_select= first_select;
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 8d639f9271d..6bb36dbb089 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -783,7 +783,7 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
const Sql_condition *err;
SELECT_LEX *sel= thd->lex->first_select_lex();
SELECT_LEX_UNIT *unit= &thd->lex->unit;
- ulonglong idx= 0;
+ ha_rows idx;
Protocol *protocol=thd->protocol;
DBUG_ENTER("mysqld_show_warnings");
@@ -808,14 +808,14 @@ bool mysqld_show_warnings(THD *thd, ulong levels_to_show)
Diagnostics_area::Sql_condition_iterator it=
thd->get_stmt_da()->sql_conditions();
- while ((err= it++))
+ for (idx= 1; (err= it++) ; idx++)
{
/* Skip levels that the user is not interested in */
if (!(levels_to_show & ((ulong) 1 << err->get_level())))
continue;
- if (++idx <= unit->offset_limit_cnt)
- continue;
- if (idx > unit->select_limit_cnt)
+ if (unit->lim.check_and_move_offset())
+ continue; // using limit offset,count
+ if (idx > unit->lim.get_select_limit())
break;
protocol->prepare_for_resend();
protocol->store(warning_level_names[err->get_level()].str,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f5e4185db92..c4f60f0551c 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3840,11 +3840,8 @@ int select_insert::send_data(List<Item> &values)
DBUG_ENTER("select_insert::send_data");
bool error=0;
- if (unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- DBUG_RETURN(0);
- }
+ if (unit->lim.check_and_move_offset())
+ DBUG_RETURN(0); // using limit offset,count
if (unlikely(thd->killed == ABORT_QUERY))
DBUG_RETURN(0);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 1b8f448553b..2c298a17391 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2321,8 +2321,7 @@ void st_select_lex_unit::init_query()
{
init_query_common();
set_linkage(GLOBAL_OPTIONS_TYPE);
- select_limit_cnt= HA_POS_ERROR;
- offset_limit_cnt= 0;
+ lim.set_unlimited();
union_distinct= 0;
prepared= optimized= optimized_2= executed= 0;
optimize_started= 0;
@@ -3462,12 +3461,7 @@ void st_select_lex_unit::set_limit(st_select_lex *sl)
{
DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
- offset_limit_cnt= sl->get_offset();
- select_limit_cnt= sl->get_limit();
- if (select_limit_cnt + offset_limit_cnt >= select_limit_cnt)
- select_limit_cnt+= offset_limit_cnt;
- else
- select_limit_cnt= HA_POS_ERROR;
+ lim.set_limit(sl->get_limit(), sl->get_offset());
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 40ba3b6e7b7..0270a4acfcc 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -816,6 +816,63 @@ void create_explain_query(LEX *lex, MEM_ROOT *mem_root);
void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root);
bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str);
+class Select_limit_counters
+{
+ ha_rows offset_limit_cnt_start,
+ select_limit_cnt, offset_limit_cnt;
+
+ public:
+ Select_limit_counters():
+ offset_limit_cnt_start(0),
+ select_limit_cnt(0), offset_limit_cnt(0)
+ {};
+
+ void set_limit(ha_rows limit, ha_rows offset)
+ {
+ offset_limit_cnt_start= offset;
+ select_limit_cnt= limit;
+ if (select_limit_cnt + offset_limit_cnt_start >=
+ select_limit_cnt)
+ select_limit_cnt+= offset_limit_cnt_start;
+ else
+ select_limit_cnt= HA_POS_ERROR;
+ reset();
+ }
+
+ void set_single_row()
+ {
+ offset_limit_cnt= offset_limit_cnt_start= 0;
+ select_limit_cnt= 1;
+ }
+
+ void reset()
+ {
+ offset_limit_cnt= offset_limit_cnt_start;
+ }
+
+ bool is_unlimited()
+ { return select_limit_cnt == HA_POS_ERROR; }
+ void set_unlimited()
+ { select_limit_cnt= HA_POS_ERROR; offset_limit_cnt= 0; }
+
+ bool check_and_move_offset()
+ {
+ if (offset_limit_cnt)
+ {
+ offset_limit_cnt--;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ void remove_offset() { offset_limit_cnt= 0; }
+
+ ha_rows get_select_limit()
+ { return select_limit_cnt; }
+ ha_rows get_offset_limit()
+ { return offset_limit_cnt; }
+};
+
+
class st_select_lex_unit: public st_select_lex_node {
protected:
TABLE_LIST result_table_list;
@@ -891,7 +948,7 @@ class st_select_lex_unit: public st_select_lex_node {
//node on which we should return current_select pointer after parsing subquery
st_select_lex *return_to;
/* LIMIT clause runtime counters */
- ha_rows select_limit_cnt, offset_limit_cnt;
+ Select_limit_counters lim;
/* not NULL if unit used in subselect, point to subselect item */
Item_subselect *item;
/*
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7d6f71cda21..9e6600d65b6 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4579,7 +4579,7 @@ mysql_execute_command(THD *thd)
select_lex->where,
select_lex->order_list.elements,
select_lex->order_list.first,
- unit->select_limit_cnt,
+ unit->lim.get_select_limit(),
lex->duplicates, lex->ignore,
&found, &updated);
MYSQL_UPDATE_DONE(res, found, updated);
@@ -4924,7 +4924,7 @@ mysql_execute_command(THD *thd)
res = mysql_delete(thd, all_tables,
select_lex->where, &select_lex->order_list,
- unit->select_limit_cnt, select_lex->options,
+ unit->lim.get_select_limit(), select_lex->options,
sel_result);
if (replaced_protocol)
@@ -5771,7 +5771,8 @@ mysql_execute_command(THD *thd)
res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
- unit->select_limit_cnt, unit->offset_limit_cnt);
+ unit->lim.get_select_limit(),
+ unit->lim.get_offset_limit());
break;
case SQLCOM_BEGIN:
@@ -6511,8 +6512,8 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
/*
Do like the original select_describe did: remove OFFSET from the
top-level LIMIT
- */
- result->reset_offset_limit();
+ */
+ result->remove_offset_limit();
if (lex->explain_json)
{
lex->explain->print_explain_json(result, lex->analyze_stmt);
@@ -7853,7 +7854,7 @@ void mysql_init_multi_delete(LEX *lex)
lex->sql_command= SQLCOM_DELETE_MULTI;
mysql_init_select(lex);
lex->first_select_lex()->select_limit= 0;
- lex->unit.select_limit_cnt= HA_POS_ERROR;
+ lex->unit.lim.set_unlimited();
lex->first_select_lex()->table_list.
save_and_clear(&lex->auxiliary_table_list);
lex->query_tables= 0;
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 6ca21aebb37..e2b7b18faac 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -404,7 +404,7 @@ bool PROFILING::show_profiles()
MEM_ROOT *mem_root= thd->mem_root;
SELECT_LEX *sel= thd->lex->first_select_lex();
SELECT_LEX_UNIT *unit= &thd->lex->unit;
- ha_rows idx= 0;
+ ha_rows idx;
Protocol *protocol= thd->protocol;
void *iterator;
DBUG_ENTER("PROFILING::show_profiles");
@@ -428,9 +428,9 @@ bool PROFILING::show_profiles()
unit->set_limit(sel);
- for (iterator= history.new_iterator();
+ for (iterator= history.new_iterator(), idx= 1;
iterator != NULL;
- iterator= history.iterator_next(iterator))
+ iterator= history.iterator_next(iterator), idx++)
{
prof= history.iterator_value(iterator);
@@ -438,9 +438,9 @@ bool PROFILING::show_profiles()
double query_time_usecs= prof->m_end_time_usecs - prof->m_start_time_usecs;
- if (++idx <= unit->offset_limit_cnt)
+ if (unit->lim.check_and_move_offset())
continue;
- if (idx > unit->select_limit_cnt)
+ if (idx > unit->lim.get_select_limit())
break;
protocol->prepare_for_resend();
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 2ee175293de..6f712750e41 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -3911,7 +3911,7 @@ bool mysql_show_binlog_events(THD* thd)
if (binary_log->is_open())
{
SELECT_LEX_UNIT *unit= &thd->lex->unit;
- ha_rows event_count, limit_start, limit_end;
+ ha_rows event_count;
my_off_t pos = MY_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
char search_file_name[FN_REFLEN], *name;
const char *log_file_name = lex_mi->log_file_name;
@@ -3926,8 +3926,6 @@ bool mysql_show_binlog_events(THD* thd)
}
unit->set_limit(thd->lex->current_select);
- limit_start= unit->offset_limit_cnt;
- limit_end= unit->select_limit_cnt;
name= search_file_name;
if (log_file_name)
@@ -4006,7 +4004,7 @@ bool mysql_show_binlog_events(THD* thd)
description_event,
opt_master_verify_checksum)); )
{
- if (event_count >= limit_start &&
+ if (!unit->lim.check_and_move_offset() &&
ev->net_send(protocol, linfo.log_file_name, pos))
{
errmsg = "Net error";
@@ -4040,11 +4038,11 @@ bool mysql_show_binlog_events(THD* thd)
pos = my_b_tell(&log);
- if (++event_count >= limit_end)
+ if (++event_count >= unit->lim.get_select_limit())
break;
}
- if (unlikely(event_count < limit_end && log.error))
+ if (unlikely(event_count < unit->lim.get_select_limit() && log.error))
{
errmsg = "Wrong offset or I/O error";
mysql_mutex_unlock(log_lock);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 978f0785887..aa4c40866a9 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1508,7 +1508,7 @@ JOIN::optimize_inner()
{
DBUG_ENTER("JOIN::optimize");
subq_exit_fl= false;
- do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
+ do_send_rows = (unit->lim.get_select_limit()) ? 1 : 0;
DEBUG_SYNC(thd, "before_join_optimize");
@@ -1579,9 +1579,9 @@ JOIN::optimize_inner()
DBUG_RETURN(-1);
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
- unit->select_limit_cnt);
+ unit->lim.get_select_limit());
/* select_limit is used to decide if we are likely to scan the whole table */
- select_limit= unit->select_limit_cnt;
+ select_limit= unit->lim.get_select_limit();
if (having || (select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
#ifdef HAVE_REF_TO_FIELDS // Not done yet
@@ -1790,9 +1790,10 @@ JOIN::optimize_inner()
thd->change_item_tree(&sel->having, having);
}
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
- (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
+ (!unit->lim.get_select_limit() &&
+ !(select_options & OPTION_FOUND_ROWS)))
{ /* Impossible cond */
- if (unit->select_limit_cnt)
+ if (unit->lim.get_select_limit())
{
DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
"Impossible HAVING" : "Impossible WHERE"));
@@ -3314,7 +3315,7 @@ bool JOIN::make_aggr_tables_info()
*/
sort_tab->filesort->limit=
(has_group_by || (join_tab + table_count > curr_tab + 1)) ?
- select_limit : unit->select_limit_cnt;
+ select_limit : unit->lim.get_select_limit();
}
if (!only_const_tables() &&
!join_tab[const_tables].filesort &&
@@ -3698,8 +3699,7 @@ JOIN::reinit()
{
DBUG_ENTER("JOIN::reinit");
- unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
- select_lex->offset_limit->val_uint() : 0);
+ unit->lim.reset();
first_record= false;
group_sent= false;
@@ -5157,7 +5157,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
for (i= 0; i < join->table_count ; i++)
records*= join->best_positions[i].records_read ?
(ha_rows)join->best_positions[i].records_read : 1;
- set_if_smaller(records, unit->select_limit_cnt);
+ set_if_smaller(records, unit->lim.get_select_limit());
join->select_lex->increase_derived_records(records);
}
}
@@ -7446,7 +7446,7 @@ best_access_path(JOIN *join,
if (!best_key &&
idx == join->const_tables &&
s->table == join->sort_by_table &&
- join->unit->select_limit_cnt >= records)
+ join->unit->lim.get_select_limit() >= records)
join->sort_by_table= (TABLE*) 1; // Must use temporary table
DBUG_VOID_RETURN;
@@ -10799,7 +10799,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
!tab->loosescan_match_tab && // (1)
((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
(!tab->const_keys.is_clear_all() && i == join->const_tables &&
- join->unit->select_limit_cnt <
+ join->unit->lim.get_select_limit() <
join->best_positions[i].records_read &&
!(join->select_options & OPTION_FOUND_ROWS))))
{
@@ -10823,7 +10823,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
(join->select_options &
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
- join->unit->select_limit_cnt), 0,
+ join->unit->lim.get_select_limit()), 0,
FALSE, FALSE) < 0)
{
/*
@@ -10837,7 +10837,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
(join->select_options &
OPTION_FOUND_ROWS ?
HA_POS_ERROR :
- join->unit->select_limit_cnt),0,
+ join->unit->lim.get_select_limit()),0,
FALSE, FALSE) < 0)
DBUG_RETURN(1); // Impossible WHERE
}
@@ -20581,7 +20581,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
++join->send_records;
- if (join->send_records >= join->unit->select_limit_cnt &&
+ if (join->send_records >= join->unit->lim.get_select_limit() &&
!join->do_send_rows)
{
/*
@@ -20599,7 +20599,7 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
}
}
- if (join->send_records >= join->unit->select_limit_cnt &&
+ if (join->send_records >= join->unit->lim.get_select_limit() &&
join->do_send_rows)
{
if (join->select_options & OPTION_FOUND_ROWS)
@@ -20740,13 +20740,13 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if (end_of_records)
DBUG_RETURN(NESTED_LOOP_OK);
- if (join->send_records >= join->unit->select_limit_cnt &&
+ if (join->send_records >= join->unit->lim.get_select_limit() &&
join->do_send_rows)
{
if (!(join->select_options & OPTION_FOUND_ROWS))
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
join->do_send_rows=0;
- join->unit->select_limit_cnt = HA_POS_ERROR;
+ join->unit->lim.set_unlimited();
}
else if (join->send_records >= join->fetch_limit)
{
@@ -20831,7 +20831,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (!(join->select_options & OPTION_FOUND_ROWS))
DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
join->do_send_rows=0;
- join->unit->select_limit_cnt = HA_POS_ERROR;
+ join->unit->lim.set_unlimited();
}
}
}
@@ -22142,7 +22142,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
(tab->join->select_options &
OPTION_FOUND_ROWS) ?
HA_POS_ERROR :
- tab->join->unit->select_limit_cnt,TRUE,
+ tab->join->unit->
+ lim.get_select_limit(),
+ TRUE,
TRUE, FALSE) <= 0;
if (res)
{
@@ -22244,7 +22246,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
select->test_quick_select(join->thd, tmp_map, 0,
join->select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR :
- join->unit->select_limit_cnt,
+ join->unit->lim.get_select_limit(),
TRUE, FALSE, FALSE);
if (cond_saved)
@@ -22671,7 +22673,7 @@ JOIN_TAB::remove_duplicates()
if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
{ // only const items with no OPTION_FOUND_ROWS
- join->unit->select_limit_cnt= 1; // Only send first row
+ join->unit->lim.set_single_row(); // Only send first row
DBUG_RETURN(false);
}
@@ -24859,7 +24861,7 @@ int JOIN::rollup_send_data(uint idx)
copy_ref_ptr_array(ref_ptrs, rollup.ref_pointer_arrays[i]);
if ((!having || having->val_int()))
{
- if (send_records < unit->select_limit_cnt && do_send_rows &&
+ if (send_records < unit->lim.get_select_limit() && do_send_rows &&
(res= result->send_data(rollup.fields[i])) > 0)
return 1;
if (!res)
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index ca8a5e7a8b3..d563301a339 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -110,11 +110,8 @@ int select_unit::send_data(List<Item> &values)
{
int rc;
int not_reported_error= 0;
- if (unit->offset_limit_cnt)
- { // using limit offset,count
- unit->offset_limit_cnt--;
- return 0;
- }
+ if (unit->lim.check_and_move_offset())
+ return 0; // using limit offset,count
if (thd->killed == ABORT_QUERY)
return 0;
if (table->no_rows_with_nulls)
@@ -883,8 +880,7 @@ bool st_select_lex_unit::prepare(TABLE_LIST *derived_arg,
else
{
sl->join->result= result;
- select_limit_cnt= HA_POS_ERROR;
- offset_limit_cnt= 0;
+ lim.set_unlimited();
if (!sl->join->procedure &&
result->prepare(sl->join->fields_list, this))
{
@@ -1317,7 +1313,7 @@ bool st_select_lex_unit::optimize()
if (sl->tvc)
{
sl->tvc->select_options=
- (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
+ (lim.is_unlimited() || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
if (sl->tvc->optimize(thd))
{
@@ -1337,13 +1333,13 @@ bool st_select_lex_unit::optimize()
set_limit(sl);
if (sl == global_parameters() || describe)
{
- offset_limit_cnt= 0;
+ lim.remove_offset();
/*
We can't use LIMIT at this stage if we are using ORDER BY for the
whole query
*/
if (sl->order_list.first || describe)
- select_limit_cnt= HA_POS_ERROR;
+ lim.set_unlimited();
}
/*
@@ -1352,7 +1348,7 @@ bool st_select_lex_unit::optimize()
Otherwise, SQL_CALC_FOUND_ROWS should be done on all sub parts.
*/
sl->join->select_options=
- (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
+ (lim.is_unlimited() || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
saved_error= sl->join->optimize();
@@ -1432,13 +1428,13 @@ bool st_select_lex_unit::exec()
set_limit(sl);
if (sl == global_parameters() || describe)
{
- offset_limit_cnt= 0;
+ lim.remove_offset();
/*
We can't use LIMIT at this stage if we are using ORDER BY for the
whole query
*/
if (sl->order_list.first || describe)
- select_limit_cnt= HA_POS_ERROR;
+ lim.set_unlimited();
}
/*
@@ -1449,14 +1445,14 @@ bool st_select_lex_unit::exec()
if (sl->tvc)
{
sl->tvc->select_options=
- (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
+ (lim.is_unlimited() || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
saved_error= sl->tvc->optimize(thd);
}
else
{
- sl->join->select_options=
- (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
+ sl->join->select_options=
+ (lim.is_unlimited() || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
saved_error= sl->join->optimize();
}
@@ -1478,9 +1474,7 @@ bool st_select_lex_unit::exec()
}
if (!sl->tvc)
saved_error= sl->join->error;
- offset_limit_cnt= (ha_rows)(sl->offset_limit ?
- sl->offset_limit->val_uint() :
- 0);
+ lim.reset();
if (likely(!saved_error))
{
examined_rows+= thd->get_examined_row_count();
@@ -1507,8 +1501,8 @@ bool st_select_lex_unit::exec()
DBUG_RETURN(1);
}
}
- if (found_rows_for_union && !sl->braces &&
- select_limit_cnt != HA_POS_ERROR)
+ if (found_rows_for_union && !sl->braces &&
+ !lim.is_unlimited())
{
/*
This is a union without braces. Remember the number of rows that
1
0