It seems, the problem is here:
(gdb) wher
#0 Dep_module::touch (this=0xa1704c0) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:358
#1 0x083850e2 in Dep_analysis_context::run_wave (this=0x991e5654, new_bound_modules=0x991e5780) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:914
#2 0x0838673e in check_func_dependency (join=0xa16edf8, dep_tables=6, it=0x991e5800, oj_tbl=0x0, cond=0xa16f1c8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:848
#3 0x08386a3c in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa152c90, list_tables=6, on_expr=0xa16f1c8, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:756
#4 0x08386857 in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa13cd7c, list_tables=7, on_expr=0x0, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:716
#5 0x08386ddc in eliminate_tables (join=0xa16edf8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:655
#6 0x0828f25c in make_join_statistics (join=0xa16edf8, tables_list=..., conds=0x0, keyuse_array=0xa16eff8) at /home/psergey/dev2/5.5/sql/sql_select.cc:3360
#7 0x08291f83 in JOIN::optimize (this=0xa16edf8) at /home/psergey/dev2/5.5/sql/sql_select.cc:1209
(gdb) p this
$134 = (Dep_module_goal *) 0xa1704c0
358 void touch()
{ unbound_args--; }
The code in Dep_module::touch() assumes that it is called from different sources.
In our case:
1. table "country" has two unique keys.
2. table "city" has no indexes at all.
#2 should prevent Dep_module_goal from ever being marked as bound. However, #1 causes dep_module_goa->touch() be called twice, and the optimizer incorrectly assumes Dep_module_goal is satisfied.
Sergei Petrunia
added a comment - It seems, the problem is here:
(gdb) wher
#0 Dep_module::touch (this=0xa1704c0) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:358
#1 0x083850e2 in Dep_analysis_context::run_wave (this=0x991e5654, new_bound_modules=0x991e5780) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:914
#2 0x0838673e in check_func_dependency (join=0xa16edf8, dep_tables=6, it=0x991e5800, oj_tbl=0x0, cond=0xa16f1c8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:848
#3 0x08386a3c in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa152c90, list_tables=6, on_expr=0xa16f1c8, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:756
#4 0x08386857 in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa13cd7c, list_tables=7, on_expr=0x0, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:716
#5 0x08386ddc in eliminate_tables (join=0xa16edf8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:655
#6 0x0828f25c in make_join_statistics (join=0xa16edf8, tables_list=..., conds=0x0, keyuse_array=0xa16eff8) at /home/psergey/dev2/5.5/sql/sql_select.cc:3360
#7 0x08291f83 in JOIN::optimize (this=0xa16edf8) at /home/psergey/dev2/5.5/sql/sql_select.cc:1209
(gdb) p this
$134 = (Dep_module_goal *) 0xa1704c0
358 void touch()
{ unbound_args--; }
The code in Dep_module::touch() assumes that it is called from different sources.
In our case:
1. table "country" has two unique keys.
2. table "city" has no indexes at all.
#2 should prevent Dep_module_goal from ever being marked as bound. However, #1 causes dep_module_goa->touch() be called twice, and the optimizer incorrectly assumes Dep_module_goal is satisfied.
what I don't understand is why the testcase fails only with InnoDB. The problem that is fixed by this patch is orthogonal to the storage engine being used.
Sergei Petrunia
added a comment - This patch fixes the testcase for this bug:
=== modified file 'sql/opt_table_elimination.cc'
— sql/opt_table_elimination.cc 2012-02-17 11:19:38 +0000
+++ sql/opt_table_elimination.cc 2013-08-21 18:02:45 +0000
@@ -892,8 +892,11 @@ bool Dep_analysis_context::run_wave(List
iter= module->init_unbound_values_iter(iter_buf);
while ((value= module->get_next_unbound_value(this, iter)))
{
value->make_bound();
new_bound_values.push_back(value);
+ if (!value->is_bound())
+
{
+ value->make_bound();
+ new_bound_values.push_back(value);
+ }
}
}
new_bound_modules->empty();
what I don't understand is why the testcase fails only with InnoDB. The problem that is fixed by this patch is orthogonal to the storage engine being used.
CREATE TABLE country ( code VARCHAR(3), name VARCHAR(64), PRIMARY KEY (code), UNIQUE KEY (name)) ENGINE=InnoDB;
...
Breakpoint 14, Dep_value_field::get_next_unbound_module (this=0x7fff9400af08, dac=0x7fffc87c5e00, iter=0x7fffc87c5d00 "`\311\002\224\377\177") at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:1742
(gdb) p field->field_name
$188 = 0x7fff9401ee59 "code"
(gdb) p *field->table_name
$189 = 0x7fff9400da90 "country"
(gdb) p key_dep->keyno
$190 = 1
That is, country.code is considered to be covered by key#1 in table `country`.
Key #1 is UNIQUE KEY(name). This is extended keys feature at work.
However, the constructor for this unique key assumes that the key as one key
part:
Breakpoint 13, Dep_module_key::Dep_module_key (this=0x7fff9402c960, table_arg=0x7fff9402c910, keyno_arg=1, n_parts_arg=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:422
note above: keyno_arg=1, n_parts_arg=1
Somehow, extended-keys property is taken into account in one place but not in the other.
Sergei Petrunia
added a comment - CREATE TABLE country ( code VARCHAR(3), name VARCHAR(64), PRIMARY KEY (code), UNIQUE KEY (name)) ENGINE=InnoDB;
...
Breakpoint 14, Dep_value_field::get_next_unbound_module (this=0x7fff9400af08, dac=0x7fffc87c5e00, iter=0x7fffc87c5d00 "`\311\002\224\377\177") at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:1742
(gdb) p field->field_name
$188 = 0x7fff9401ee59 "code"
(gdb) p *field->table_name
$189 = 0x7fff9400da90 "country"
(gdb) p key_dep->keyno
$190 = 1
That is, country.code is considered to be covered by key#1 in table `country`.
Key #1 is UNIQUE KEY(name). This is extended keys feature at work.
However, the constructor for this unique key assumes that the key as one key
part:
Breakpoint 13, Dep_module_key::Dep_module_key (this=0x7fff9402c960, table_arg=0x7fff9402c910, keyno_arg=1, n_parts_arg=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:422
note above: keyno_arg=1, n_parts_arg=1
Somehow, extended-keys property is taken into account in one place but not in the other.
It seems, usable_key_parts should be used instead?
Sergei Petrunia
added a comment -
Dep_value_table *Dep_analysis_context::create_table_value(TABLE *table)
has this code
if (key->flags & HA_NOSAME)
{
Dep_module_key *key_dep;
if (!(key_dep= new Dep_module_key(tbl_dep, i, key->key_parts)))
As for key->key_parts:
(gdb) p *key
$200 = {key_length = 69, flags = 105, key_parts = 1, usable_key_parts = 2,
ext_key_parts = 2 ...
It seems, usable_key_parts should be used instead?
Table elimination uses primary/unique key definitions to know which set of
columns uniquely defines the table record.
Extending the binding column set makes things worse for table elimination.
Without extended keys, table elimination sees
UNIQUE KEY(col1),
PRIMARY KEY (pk_col)
and is able to infer that "col1=...." makes the table bound.
With extended keys, table elimination sees:
UNIQUE KEY(col1, pk_col)
PRIMARY KEY (pk_col)
and this doesn't allow to infer that "col1=..." makes the table bound.
Sergei Petrunia
added a comment - Handling extended keys in table elimination.
Table elimination uses primary/unique key definitions to know which set of
columns uniquely defines the table record.
Extending the binding column set makes things worse for table elimination.
Without extended keys, table elimination sees
UNIQUE KEY(col1),
PRIMARY KEY (pk_col)
and is able to infer that "col1=...." makes the table bound.
With extended keys, table elimination sees:
UNIQUE KEY(col1, pk_col)
PRIMARY KEY (pk_col)
and this doesn't allow to infer that "col1=..." makes the table bound.
People
Sergei Petrunia
Elena Stepanova
Votes:
0Vote for this issue
Watchers:
6Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":898.5,"ttfb":267.5,"pageVisibility":"visible","entityId":25024,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":1,"journeyId":"b53709af-34d5-47ae-b296-728683ecdac5","navigationType":0,"readyForUser":976.6999999880791,"redirectCount":0,"resourceLoadedEnd":718.7999999821186,"resourceLoadedStart":298.09999999403954,"resourceTiming":[{"duration":131.2999999821186,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2bv2/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":298.09999999403954,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":298.09999999403954,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":429.39999997615814,"responseStart":0,"secureConnectionStart":0},{"duration":131.30000001192093,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2bv2/820016/12ta74/2380add21a9a1006587582385952de73/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":298.39999997615814,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":298.39999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":429.69999998807907,"responseStart":0,"secureConnectionStart":0},{"duration":140.09999999403954,"initiatorType":"script","name":"https://jira.mariadb.org/s/e9b27a47da5fb0f74a35acd57e9847fb-CDN/lu2bv2/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":298.59999999403954,"connectEnd":298.59999999403954,"connectStart":298.59999999403954,"domainLookupEnd":298.59999999403954,"domainLookupStart":298.59999999403954,"fetchStart":298.59999999403954,"redirectEnd":0,"redirectStart":0,"requestStart":298.59999999403954,"responseEnd":438.69999998807907,"responseStart":438.69999998807907,"secureConnectionStart":298.59999999403954},{"duration":195.40000000596046,"initiatorType":"script","name":"https://jira.mariadb.org/s/c32eb0da7ad9831253f8397e6cc26afd-CDN/lu2bv2/820016/12ta74/2380add21a9a1006587582385952de73/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":298.7999999821186,"connectEnd":298.7999999821186,"connectStart":298.7999999821186,"domainLookupEnd":298.7999999821186,"domainLookupStart":298.7999999821186,"fetchStart":298.7999999821186,"redirectEnd":0,"redirectStart":0,"requestStart":298.7999999821186,"responseEnd":494.19999998807907,"responseStart":494.19999998807907,"secureConnectionStart":298.7999999821186},{"duration":199.5,"initiatorType":"script","name":"https://jira.mariadb.org/s/bc0bcb146314416123c992714ee00ff7-CDN/lu2bv2/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":299.09999999403954,"connectEnd":299.09999999403954,"connectStart":299.09999999403954,"domainLookupEnd":299.09999999403954,"domainLookupStart":299.09999999403954,"fetchStart":299.09999999403954,"redirectEnd":0,"redirectStart":0,"requestStart":299.09999999403954,"responseEnd":498.59999999403954,"responseStart":498.59999999403954,"secureConnectionStart":299.09999999403954},{"duration":200,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bv2/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":299.19999998807907,"connectEnd":299.19999998807907,"connectStart":299.19999998807907,"domainLookupEnd":299.19999998807907,"domainLookupStart":299.19999998807907,"fetchStart":299.19999998807907,"redirectEnd":0,"redirectStart":0,"requestStart":299.19999998807907,"responseEnd":499.19999998807907,"responseStart":499.19999998807907,"secureConnectionStart":299.19999998807907},{"duration":200.19999998807907,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bv2/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":299.5,"connectEnd":299.5,"connectStart":299.5,"domainLookupEnd":299.5,"domainLookupStart":299.5,"fetchStart":299.5,"redirectEnd":0,"redirectStart":0,"requestStart":299.5,"responseEnd":499.69999998807907,"responseStart":499.69999998807907,"secureConnectionStart":299.5},{"duration":282.19999998807907,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2bv2/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":299.59999999403954,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":299.59999999403954,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":581.7999999821186,"responseStart":0,"secureConnectionStart":0},{"duration":200.7000000178814,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":299.7999999821186,"connectEnd":299.7999999821186,"connectStart":299.7999999821186,"domainLookupEnd":299.7999999821186,"domainLookupStart":299.7999999821186,"fetchStart":299.7999999821186,"redirectEnd":0,"redirectStart":0,"requestStart":299.7999999821186,"responseEnd":500.5,"responseStart":500.5,"secureConnectionStart":299.7999999821186},{"duration":282.10000002384186,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2bv2/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":299.89999997615814,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":299.89999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":582,"responseStart":0,"secureConnectionStart":0},{"duration":201.19999998807907,"initiatorType":"script","name":"https://jira.mariadb.org/s/719848dd97ebe0663199f49a3936487a-CDN/lu2bv2/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":300.09999999403954,"connectEnd":300.09999999403954,"connectStart":300.09999999403954,"domainLookupEnd":300.09999999403954,"domainLookupStart":300.09999999403954,"fetchStart":300.09999999403954,"redirectEnd":0,"redirectStart":0,"requestStart":300.09999999403954,"responseEnd":501.2999999821186,"responseStart":501.2999999821186,"secureConnectionStart":300.09999999403954},{"duration":319.60000002384186,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bv2/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":300.89999997615814,"connectEnd":300.89999997615814,"connectStart":300.89999997615814,"domainLookupEnd":300.89999997615814,"domainLookupStart":300.89999997615814,"fetchStart":300.89999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":300.89999997615814,"responseEnd":620.5,"responseStart":620.5,"secureConnectionStart":300.89999997615814},{"duration":417.90000000596046,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bv2/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":300.89999997615814,"connectEnd":300.89999997615814,"connectStart":300.89999997615814,"domainLookupEnd":300.89999997615814,"domainLookupStart":300.89999997615814,"fetchStart":300.89999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":300.89999997615814,"responseEnd":718.7999999821186,"responseStart":718.7999999821186,"secureConnectionStart":300.89999997615814},{"duration":108.40000000596046,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":609.1999999880791,"connectEnd":609.1999999880791,"connectStart":609.1999999880791,"domainLookupEnd":609.1999999880791,"domainLookupStart":609.1999999880791,"fetchStart":609.1999999880791,"redirectEnd":0,"redirectStart":0,"requestStart":609.1999999880791,"responseEnd":717.5999999940395,"responseStart":717.5999999940395,"secureConnectionStart":609.1999999880791}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":72,"responseStart":267,"responseEnd":289,"domLoading":295,"domInteractive":1076,"domContentLoadedEventStart":1076,"domContentLoadedEventEnd":1124,"domComplete":2097,"loadEventStart":2097,"loadEventEnd":2097,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":1051},{"name":"bigPipe.sidebar-id.end","time":1051.7999999821186},{"name":"bigPipe.activity-panel-pipe-id.start","time":1052},{"name":"bigPipe.activity-panel-pipe-id.end","time":1053.699999988079},{"name":"activityTabFullyLoaded","time":1142.699999988079}],"measures":[],"correlationId":"a054974c3f1fb5","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":119,"dbReadsTimeInMs":11,"dbConnsTimeInMs":20,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
It seems, the problem is here:
(gdb) wher
#0 Dep_module::touch (this=0xa1704c0) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:358
#1 0x083850e2 in Dep_analysis_context::run_wave (this=0x991e5654, new_bound_modules=0x991e5780) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:914
#2 0x0838673e in check_func_dependency (join=0xa16edf8, dep_tables=6, it=0x991e5800, oj_tbl=0x0, cond=0xa16f1c8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:848
#3 0x08386a3c in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa152c90, list_tables=6, on_expr=0xa16f1c8, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:756
#4 0x08386857 in eliminate_tables_for_list (join=0xa16edf8, join_list=0xa13cd7c, list_tables=7, on_expr=0x0, tables_used_elsewhere=1) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:716
#5 0x08386ddc in eliminate_tables (join=0xa16edf8) at /home/psergey/dev2/5.5/sql/opt_table_elimination.cc:655
#6 0x0828f25c in make_join_statistics (join=0xa16edf8, tables_list=..., conds=0x0, keyuse_array=0xa16eff8) at /home/psergey/dev2/5.5/sql/sql_select.cc:3360
#7 0x08291f83 in JOIN::optimize (this=0xa16edf8) at /home/psergey/dev2/5.5/sql/sql_select.cc:1209
(gdb) p this
$134 = (Dep_module_goal *) 0xa1704c0
358 void touch()
{ unbound_args--; }The code in Dep_module::touch() assumes that it is called from different sources.
In our case:
1. table "country" has two unique keys.
2. table "city" has no indexes at all.
#2 should prevent Dep_module_goal from ever being marked as bound. However, #1 causes dep_module_goa->touch() be called twice, and the optimizer incorrectly assumes Dep_module_goal is satisfied.