-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
MDEV-36483 Optimizer Trace Replay step #1: dump DDLs of tables/views #4034
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
eec9242
to
969a713
Compare
c31b8fd
to
c1c1a62
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I've already requested: Please apply the output of
git diff -U0 --no-color --relative 4b79d7b8ee557d53a859aedec839b8673585b514 | clang-format-diff -p1 -i
Here it is:
diff --git a/sql/opt_trace_ddl_info.cc b/sql/opt_trace_ddl_info.cc
index c9ce9645781..d6b729efa60 100644
--- a/sql/opt_trace_ddl_info.cc
+++ b/sql/opt_trace_ddl_info.cc
@@ -12,7 +12,8 @@
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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335
+ USA */
#include "opt_trace_ddl_info.h"
#include "sql_show.h"
@@ -26,7 +27,7 @@
@file
@brief
- Stores the ddls of the tables, and views that are used
+ Stores the ddls of the tables, and views that are used
in either SELECT, INSERT, DELETE, and UPDATE queries,
into the optimizer trace. All the ddls are stored together
at one place as a JSON array object with name "list_ddls"
@@ -42,7 +43,8 @@ struct DDL_Info_Record
helper function to know the key portion of the record
that is stored in hash, and record list.
*/
-static const uchar *get_rec_key(const void *entry_, size_t *length, my_bool flags)
+static const uchar *get_rec_key(const void *entry_, size_t *length,
+ my_bool flags)
{
auto entry= static_cast<const DDL_Info_Record *>(entry_);
*length= strlen(entry->name);
@@ -52,7 +54,8 @@ static const uchar *get_rec_key(const void *entry_, size_t *length, my_bool flag
/*
helper function to free record from the hash
*/
-static void free_rec(void *entry_) {
+static void free_rec(void *entry_)
+{
auto entry= static_cast<DDL_Info_Record *>(entry_);
my_free(entry->name);
my_free(entry->stmt);
@@ -110,15 +113,15 @@ static void create_view_def(THD *thd, TABLE_LIST *table, String *name,
}
/*
- Stores the ddls of the tables, and views that are used
+ Stores the ddls of the tables, and views that are used
in either SELECT, INSERT, DELETE, and UPDATE queries,
into the optimizer trace.
Global query_tables are read in reverse order from the thd->lex,
and a record with table_name, and ddl of the table are created.
Hash is used to store the records, where in no duplicates
are stored. dbName_plus_tableName is used as a key to discard any
- duplicates. If a new record that is created is not in the hash,
- then that is dumped into the trace.
+ duplicates. If a new record that is created is not in the hash,
+ then that is dumped into the trace.
*/
void store_table_definitions_in_trace(THD *thd)
{
diff --git a/sql/opt_trace_ddl_info.h b/sql/opt_trace_ddl_info.h
index 7e130ce6a05..8f4e8ef49c0 100644
--- a/sql/opt_trace_ddl_info.h
+++ b/sql/opt_trace_ddl_info.h
@@ -12,7 +12,8 @@
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 Street, Fifth Floor, Boston, MA 02110-1335 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335
+ USA */
#ifndef OPT_TRACE_DDL_INFO
#define OPT_TRACE_DDL_INFO
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 609e4ac242d..9644a912b2e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -92,7 +92,7 @@
#include "opt_trace.h"
#include "mysql/psi/mysql_sp.h"
-#include "my_json_writer.h"
+#include "my_json_writer.h"
#include "opt_trace_ddl_info.h"
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
sql/sql_show.h
Outdated
@@ -82,7 +82,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond); | |||
int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet, | |||
Table_specification_st *create_info_arg, | |||
enum_with_db_name with_db_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this change.
sql/sql_class.cc
Outdated
@@ -1728,7 +1728,6 @@ void THD::cleanup(void) | |||
statement_rcontext_reinit(); | |||
auto_inc_intervals_forced.empty(); | |||
auto_inc_intervals_in_cur_stmt_for_binlog.empty(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this change also please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More smaller comments.
sql/opt_trace_ddl_info.cc
Outdated
tbl->table->s->tmp_table == TRANSACTIONAL_TMP_TABLE))) | ||
{ | ||
size_t name_len= | ||
strlen(tbl->table_name.str) + strlen(tbl->get_db_name().str) + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use tbl->table_name.length, not strlen. Same with get_db_name.length.
sql/opt_trace_ddl_info.cc
Outdated
else | ||
show_create_table(thd, tbl, &ddl, NULL, WITH_DB_NAME); | ||
|
||
buf= ddl.c_ptr(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use ddl.length(), no need for strlen.
sql/opt_trace_ddl_info.h
Outdated
|
||
void store_table_definitions_in_trace(THD *thd); | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add new line at end of file.
sql/opt_trace_ddl_info.cc
Outdated
} | ||
my_hash_free(&hash); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add newline at the end of file.
sql/opt_trace_ddl_info.cc
Outdated
return true; | ||
else if (get_table_category(tbl->get_db_name(), tbl->get_table_name()) != | ||
TABLE_CATEGORY_USER || | ||
strcmp(tbl->get_db_name().str, "sys") == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why strcmp(tbl->get_db_name().str, "sys")
? Please explain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any "sys" table should return true. I felt, get_table_category() has fewer restrictions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the "sys" database, I see only VIEWs (over information_schema and performance_schema tables) and one base table - sys.sys_config
.
I don't think factoring out "sys" gives any value here, please remove it.
P_S and I_S tables are filtered out by the get_table_category()...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the "sys" database, I see only VIEWs (over information_schema and performance_schema tables) and one base table -
sys.sys_config
. I don't think factoring out "sys" gives any value here, please remove it.P_S and I_S tables are filtered out by the get_table_category()...
Yes, I saw some of the tests having sys.sys_config
actually failed, when invoking show_create_table().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use get_table_category
or, if the TABLE_SHARE
is somehow available at this point in the code, you can use TABLE_SHARE::table_category
to find the type of table as given in the enum_table_category
enumeration. It seems that system tables should be marked as TABLE_CATEGORY_SYSTEM
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use
get_table_category
or, if theTABLE_SHARE
is somehow available at this point in the code, you can useTABLE_SHARE::table_category
to find the type of table as given in theenum_table_category
enumeration. It seems that system tables should be marked asTABLE_CATEGORY_SYSTEM
.
Yes, removed the strcmp(tbl->get_db_name().str, "sys") == 0
check
sql/opt_trace_ddl_info.cc
Outdated
The record has full table_name, | ||
and ddl of the table/view. | ||
*/ | ||
static void dump_table_definition(THD *thd, DDL_Info_Record *rec) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apparently this is also used for dumping VIEWs. Please rename.
sql/opt_trace_ddl_info.cc
Outdated
tbl->table->s->tmp_table == TRANSACTIONAL_TMP_TABLE))) | ||
{ | ||
size_t name_len= | ||
tbl->get_table_name().length + tbl->get_db_name().length + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this allocates memory for db_name, the '.' and the table_name. Where is the space for \0 at the end?
Why not use String object here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, this allocates memory for db_name, the '.' and the table_name. Where is the space for \0 at the end? Why not use String object here?
Yes, I could have used the String object. But, this requires allocating new memory anyways, so as to copy the string contents, as the string object is freed after each iteration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not see any tests for querying tables located in different databases. If they are not there, please add them.
This feature stores the ddls of the tables/views that are used in a query, to the optimizer trace. It is currently controlled by a system variable store_ddls_in_optimizer_trace, and is not enabled by default. All the ddls will be stored in a single json array, with each element having table/view name, and the associated create definition of the table/view. The approach taken is to read global query_tables from the thd->lex, and read them in reverse. Create a record with table_name, ddl of the table and add the table_name to the hash, along with dumping the information to the trace. dbName_plus_tableName is used as a key, and the duplicate entries are not added to the hash. The main suite tests are also run with the feature enabled, and they all succeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, there's no need to add new commits to the PR for each review update. You can amend the commit locally and force-push to the PR. GitHub still provides a way to compare intermediate changes in such a case. And it's easier for reviewers to see the changes in one commit (or in two, if there was some prior refactoring that had to occur before the feature work). In this case, please squash all of the commits to one commit as that's what will be merged to main
in the end (and be sure to update the commit message so that it's clean for the final product).
The tests are not passing on my Linux system, here is the result I see:
CURRENT_TEST: main.opt_trace_store_ddls
--- /Users/dgosselin/1-server/mysql-test/main/opt_trace_store_ddls.result 2025-05-30 10:11:28.972377130 -0400
+++ /Users/dgosselin/1-server/mysql-test/main/opt_trace_store_ddls.reject 2025-05-30 10:15:56.882183940 -0400
@@ -32,9 +32,6 @@
select json_detailed(json_extract(trace, '$**.list_ddls'))
from information_schema.optimizer_trace;
json_detailed(json_extract(trace, '$**.list_ddls'))
-[
- []
-]
#
# disable optimizer_trace, but enable store_ddls_in_optimizer_trace
# there should be no trace here as well
@@ -47,9 +44,6 @@
select json_detailed(json_extract(trace, '$**.list_ddls'))
from information_schema.optimizer_trace;
json_detailed(json_extract(trace, '$**.list_ddls'))
-[
- []
-]
#
# enable optimizer_trace, but disable store_ddls_in_optimizer_trace
# trace result should be empty
Result length mismatch
sql/sys_vars.cc
Outdated
@@ -3108,6 +3108,13 @@ static Sys_var_ulong Sys_optimizer_trace_max_mem_size( | |||
SESSION_VAR(optimizer_trace_max_mem_size), CMD_LINE(REQUIRED_ARG), | |||
VALID_RANGE(0, ULONG_MAX), DEFAULT(1024 * 1024), BLOCK_SIZE(1)); | |||
|
|||
static Sys_var_mybool Sys_store_ddls_in_optimizer_trace( | |||
"store_ddls_in_optimizer_trace", | |||
"Controls storing of ddls of all the tables " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Elsewhere in this file, "ddls" is capitalized as "DDLs". Please change this to "DDLs" for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
sql/opt_trace_ddl_info.cc
Outdated
{ | ||
if (tbl->table_function) | ||
return true; | ||
else if (tbl->schema_table) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not necessary to have else if
after a return: https://blog.mozilla.org/nnethercote/2009/08/31/no-else-after-return-considered-harmful/
You can write just
if (tbl->table_function || tbl->schema_table)
return true;
if (get_table_category...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also replace the last if statement with a return:
return (get_table_category(tbl->get_db_name(), tbl->get_table_name()) !=
TABLE_CATEGORY_USER ||
tbl->table->s->tmp_table == INTERNAL_TMP_TABLE);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, done
sql/opt_trace_ddl_info.cc
Outdated
return true; | ||
else if (get_table_category(tbl->get_db_name(), tbl->get_table_name()) != | ||
TABLE_CATEGORY_USER || | ||
strcmp(tbl->get_db_name().str, "sys") == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use get_table_category
or, if the TABLE_SHARE
is somehow available at this point in the code, you can use TABLE_SHARE::table_category
to find the type of table as given in the enum_table_category
enumeration. It seems that system tables should be marked as TABLE_CATEGORY_SYSTEM
.
sql/opt_trace_ddl_info.cc
Outdated
Json_writer_object ddl_wrapper(thd); | ||
ddl_wrapper.add("name", rec->name); | ||
size_t non_esc_stmt_len= strlen(rec->stmt); | ||
size_t escape_stmt_len= 4 * non_esc_stmt_len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment describing what 4
is. If possible, please define it in terms of some other type (e.g., sizeof(uint32_t)
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
sql/opt_trace_ddl_info.cc
Outdated
get_rec_key, free_rec, HASH_UNIQUE); | ||
while (TABLE_LIST *tbl= li++) | ||
{ | ||
if (tbl->is_view() || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please invert the logic of this if
and make it continue
. You'll improve legibility by keeping the happy path of the code "to the left" (as de-dented as possible): https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea88
This entire loop is inside this conditional as it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done.
sql/opt_trace_ddl_info.cc
Outdated
tbl->table->s->tmp_table == TRANSACTIONAL_TMP_TABLE))) | ||
{ | ||
size_t name_len= | ||
strlen(tbl->table_name.str) + strlen(tbl->get_db_name().str) + 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the +1
for a dot separator or for NULL
terminator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the
+1
for a dot separator or forNULL
terminator?
for the dot separator
sql/opt_trace_ddl_info.cc
Outdated
my_free(full_name); | ||
else | ||
{ | ||
String ddl(2048); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is 2048 arbitrarily chosen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
sql/opt_trace_ddl_info.cc
Outdated
(char *) my_malloc(key_memory_trace_ddl_info, name_len, 0); | ||
strcpy(full_name, tbl->get_db_name().str); | ||
strcat(full_name, "."); | ||
strcat(full_name, tbl->table_name.str); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that there's no byte allocated for null terminator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was an old change. It got corrected in the later commit.
sql/opt_trace_ddl_info.cc
Outdated
buf_copy= (char *) my_malloc(key_memory_trace_ddl_info, buf_len, 0); | ||
strcpy(buf_copy, buf); | ||
rec->name= full_name; | ||
rec->stmt= buf_copy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider storing the name and statement lengths as members in the record, so there will be no need to compute strlen
again elsewhere (if needed).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure. done
This is strange. This shouldn't have happened. Test when ran locally forced me to include this change in the result file. Changed the test a bit now. Everything is successful now. |
848a670
to
1c05ec7
Compare
Please apply this patch: diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 74ee3adf73c..856e51c596b 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -155,7 +155,7 @@ SET (SQL_SOURCE
sql_profile.cc event_parse_data.cc sql_alter.cc
sql_signal.cc mdl.cc sql_admin.cc
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
- sql_reload.cc opt_trace_ddl_info.cc
+ sql_reload.cc
# added in MariaDB:
grant.cc
@@ -187,6 +187,7 @@ SET (SQL_SOURCE
rowid_filter.cc rowid_filter.h
optimizer_costs.h optimizer_defaults.h
opt_trace.cc
+ opt_trace_ddl_info.cc
table_cache.cc encryption.cc temporary_tables.cc
json_table.cc
proxy_protocol.cc backup.cc xa.cc
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index fe7b143971d..5901e3fa5aa 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -2376,7 +2376,17 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
DBUG_ASSERT(part < m_file_tot_parts);
DBUG_ASSERT(m_file[part]);
dummy_info.data_file_name= dummy_info.index_file_name = NULL;
- m_file[part]->update_create_info(&dummy_info);
+ /*
+ store_table_definitions_in_trace()/show_create_table() may attempt
+ to produce DDL for a table which has only some partitions open.
+
+ We can't get options for unopened partitions. They are not relevant
+ for purpose, so it's ok to skip printing their options.
+ */
+ if (m_file[part]->is_open())
+ m_file[part]->update_create_info(&dummy_info);
+ else
+ dummy_info.init();
sub_elem->data_file_name = (char*) dummy_info.data_file_name;
sub_elem->index_file_name = (char*) dummy_info.index_file_name;
}
@@ -2385,7 +2395,14 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
{
DBUG_ASSERT(m_file[i]);
dummy_info.data_file_name= dummy_info.index_file_name= NULL;
- m_file[i]->update_create_info(&dummy_info);
+ /*
+ A partition might not be open, see above note about
+ store_table_definitions_in_trace()
+ */
+ if (m_file[i]->is_open())
+ m_file[i]->update_create_info(&dummy_info);
+ else
+ dummy_info.init();
part_elem->data_file_name = (char*) dummy_info.data_file_name;
part_elem->index_file_name = (char*) dummy_info.index_file_name;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 6ff65a18f63..d26a8ca734c 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -11446,9 +11446,6 @@ ha_innobase::update_create_info(
/*============================*/
HA_CREATE_INFO* create_info) /*!< in/out: create info */
{
- if (!this->is_open())
- return;
-
if (!(create_info->used_fields & HA_CREATE_USED_AUTO)) {
info(HA_STATUS_AUTO);
create_info->auto_increment_value = stats.auto_increment_value;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 4def56484c9..83b8045f16f 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -2228,9 +2228,6 @@ THR_LOCK_DATA **ha_myisam::store_lock(THD *thd,
void ha_myisam::update_create_info(HA_CREATE_INFO *create_info)
{
- if (!this->is_open())
- return;
-
ha_myisam::info(HA_STATUS_AUTO | HA_STATUS_CONST);
if (!(create_info->used_fields & HA_CREATE_USED_AUTO))
{ Please make create_view_def() just accept TABLE_LIST *view and extract definition from there. |
1c05ec7
to
551a4bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My suggestion to use the mem root is not a blocker, so if it doesn't work in this case don't worry about it. But we have some other efforts afoot by another team to track memory fragmentation and ideally all of our allocations would be via the mem root interface, in part to centralize memory allocations and simplify memory usage statistics.
sql/opt_trace_ddl_info.cc
Outdated
} | ||
|
||
/* | ||
Determines whether the tbl is a USER Defined table or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider simplifying this comment to read something like this:
@return true when the tbl argument is not a user-defined table, or if tbl is an internal temporary table or if tbl is a table belonging to the information_schema database.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
sql/opt_trace_ddl_info.cc
Outdated
void store_table_definitions_in_trace(THD *thd) | ||
{ | ||
LEX *lex= thd->lex; | ||
if (thd->variables.optimizer_trace && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invert the logic of this if
statement and return early. Then the function will be less indented and easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
sql/opt_trace_ddl_info.cc
Outdated
for (TABLE_LIST *tbl= thd->lex->query_tables; tbl; tbl= tbl->next_global) | ||
tables_list.push_front(tbl); | ||
|
||
if (tables_list.is_empty() || tables_list.elements == 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did checking thd->lex->query_tables == thd->lex->query_tables_last
at the start of this function not work?. You could return early and also get rid of this check here. I noticed on the PR that GitHub chose to hide four of my review comments behind another link, I don't know why it does that because it is not helpful for anybody.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry, didn't realize this.
It actually works.
sql/opt_trace_ddl_info.cc
Outdated
continue; | ||
|
||
ddl_key= | ||
(DDL_Key *) my_malloc(key_memory_trace_ddl_info, sizeof(DDL_Key), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is another candidate for using the mem root.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
sql/opt_trace_ddl_info.cc
Outdated
show_create_table(thd, tbl, &ddl, NULL, WITH_DB_NAME); | ||
|
||
name_copy= | ||
(char *) my_malloc(key_memory_trace_ddl_info, name.length() + 1, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(and here too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, done
Please look at these and squash into the patch if there are no objections:
|
Also, let's make it future-proof: please rename |
Yeah, sure Dave. Changed the code to use thd->alloc(), and it works. |
sure. done |
f4b2e4d
to
dd68efd
Compare
sure, done |
dd68efd
to
902737f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look though this patch https://gist.github.com/spetrunia/85aae76ba071221b9d5dc203562ba68a
doing
- more error handling! particularly checking of json_escape return value is important
- cleanups
- removal of spaces-at-line-ends.
Apply it and then it looks good.
902737f
to
eb4d1ac
Compare
sure, Thanks Sergei. |
eb4d1ac
to
71dba7d
Compare
It was observed that, when doing multiple DELETE on tables: -> if there was duplicate data to delete, then no ddls were dumped to the trace. -> However, when tested with no data being deleted from the tables, then ddls of the tables were getting dumped to the trace. The problem is that store_tables_context_in_trace() is not getting invoked, from mysql_execute_command() in all the situations. The reason is that multi-table DELETE returned error when it had deleted duplicate rows. Multi-table DELETE actually finds record combinations to delete, and when it has found let's say {t1.rowX, t2.rowY, t3.rowZ}, it will attempt to save t1.rowX in the temptable for t1, t2.rowY in the temptable for t2 and so forth. When saving the row to be deleted, in the temp table, it can encounter error 121 (HA_ERR_FOUND_DUPP_KEY), and it is propagated to the caller. As a fix, I have marked that there is no error when HA_ERR_FOUND_DUPP_KEY error_code is noticed in the multi_delete::send_data()
Pull request created in: https://jira.mariadb.org/browse/MDEV-36483