[MDEV-27188] Suppress optimizer output when executing prepare Created: 2021-12-07  Updated: 2022-03-22

Status: Open
Project: MariaDB Server
Component/s: Optimizer
Fix Version/s: None

Type: Task Priority: Major
Reporter: Sergei Petrunia Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 0
Labels: None


 Description   

Filing this based on igor's input on Slack:

Igor wrote:

No, I want to suppress output to optimizer only when executing PREPARE. I actually would like not to have anything in opt trace after having executed PREPARE stmt FROM ... . LEX::context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE tells you that you are executing PREPARE stmt FROM

I've got no clue why this is needed but let's implement it.

Initial patch:

diff --git a/sql/opt_trace.cc b/sql/opt_trace.cc
index ba9220cac44..80c51eb006c 100644
--- a/sql/opt_trace.cc
+++ b/sql/opt_trace.cc
@@ -489,7 +489,8 @@ Opt_trace_start::Opt_trace_start(THD *thd, TABLE_LIST *tbl,
       !list_has_optimizer_trace_table(tbl) &&
       !sets_var_optimizer_trace(sql_command, set_vars) &&
       !thd->system_thread &&
-      !ctx->disable_tracing_if_required())
+      !ctx->disable_tracing_if_required() &&
+      !(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE))
   {
     ctx->start(thd, tbl, sql_command, query, query_length, query_charset,
                thd->variables.optimizer_trace_max_mem_size);



 Comments   
Comment by Sergei Petrunia [ 2021-12-07 ]

Igor's input: @spetrunia: I applied your diff

to my tree. It fixed the rdiff problem (it's not needed anymore). But now I have a failure for the first test case from main.opt_trace_security in --ps-protocol:

--- /home/igor/maria-git/10.6/mysql-test/main/opt_trace_security.result 2021-05-03 18:52:25.842703058 -0700
+++ /home/igor/maria-git/10.6/mysql-test/main/opt_trace_security.reject 2021-11-30 21:30:40.772008878 -0800
@@ -16,7 +16,6 @@
 ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
 select * from information_schema.OPTIMIZER_TRACE;
 QUERY  TRACE   MISSING_BYTES_BEYOND_MAX_MEM_SIZE       INSUFFICIENT_PRIVILEGES
-               0       1
 set optimizer_trace="enabled=off";
 grant select(a)  on db1.t1 to 'foo'@'%';
 set optimizer_trace="enabled=on";

@spetrunia: I still don't understand why we need Opt_trace_start constructor anywhere in sql_prepare.cc code.

Comment by Sergei Petrunia [ 2021-12-07 ]

The code in sql_prepare.cc has nothing to do with the above. I have:

--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2439,10 +2439,11 @@ static bool check_prepared_statement(Prepared_statement *stmt)
     For the optimizer trace, this is the symmetric, for statement preparation,
     of what is done at statement execution (in mysql_execute_command()).
   */
+#if 0  
   Opt_trace_start ots(thd, tables, lex->sql_command, &lex->var_list,
                       thd->query(), thd->query_length(),
                       thd->variables.character_set_client);
-
+#endif
   Json_writer_object trace_command(thd);
   Json_writer_array trace_command_steps(thd, "steps");

and the main.opt_trace_security --ps-protocol still fails in the same way.

Comment by Sergei Petrunia [ 2021-12-07 ]

Also, Igor reports that :

I applied your diff .... to my tree. It fixed the rdiff problem (it's not needed anymore).

I do not confirm this. If I remove mysql-test/main/opt_trace,ps.rdiff file, then ./mtr --ps-protocol main.opt_trace starts to fail for me.

Comment by Sergei Petrunia [ 2021-12-07 ]

Investigating the issue in main.opt_trace_security.

Regular execution

set optimizer_trace="enabled=on";
--error 1142
select * from db1.t1;

Tracing starts, but then eventually Opt_trace_stmt::missing_privilege() is called and so tracing is aborted.

we end up with I_S.OPTIMIZER_TRACE having one line which has an empty trace and INSUFFICIENT_PRIVILEGES=1.

Prepared statement execution

1. The client issues a Prepare command for select * from db1.t1. On the server, mysqld_stmt_prepare is called.

2. Tracing is not started because of this patch's logic.

3. A missing permission is detected. my_error(ER_TABLEACCESS_DENIED_ERROR, ...) is called.

4. Prepare finishes. Note that it did not produce any optimizer trace.

5. the client sees that Prepare command failed and does NOT issue an Execute command.

6. The next statement,

select * from information_schema.OPTIMIZER_TRACE;

produces nothing, because the optimizer trace was never saved.

This is why we get this difference in test output:

 ERROR 42000: SELECT command denied to user 'foo'@'localhost' for table 't1'
 select * from information_schema.OPTIMIZER_TRACE;
 QUERY  TRACE   MISSING_BYTES_BEYOND_MAX_MEM_SIZE       INSUFFICIENT_PRIVILEGES
-               0       1
 set optimizer_trace="enabled=off";
 grant select(a)  on db1.t1 to 'foo'@'%';
 set optimizer_trace="enabled=on";

Comment by Sergei Petrunia [ 2021-12-17 ]

bb-10.7-mdev27188. (This probably won't go into 10.7. Either to 10.8 or to other earlier versions)

Generated at Thu Feb 08 09:51:00 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.