Performed re-factoring and re-structuring of the code for mwl#248:
- Moved the definitions of the classes to store data from persistent statistical tables into statistics.h, leaving in other internal data structures only references to the corresponding objects. - Defined class Column_statistics_collected derived from the class Column_statistics. This is a helper class to collect statistics on columns. - Moved references to read statistics to TABLE SHARE, leaving the the reference to the collected statistics in TABLE. - Added a new clone method for the class Field allowing to clone fields attached to table shares. It was was used to create fields for min/max values in the memory of the table share. A lso: - Added procedures to allocate memory for statistical data in the table share memory and in table memory. Also: - Added a test case demonstrating how ANALYZE could work in parallel to collect statistics on different indexes of the same table. - Added a test two demonstrate how two connections working simultaneously could allocate memory for statistical data in the table share memory.
This commit is contained in:
parent
cb0a5c84b6
commit
8c499274da
@ -334,6 +334,122 @@ and o_orderkey=l_orderkey and p_partkey=l_partkey;
|
|||||||
o_orderkey p_partkey
|
o_orderkey p_partkey
|
||||||
5895 200
|
5895 200
|
||||||
set optimizer_switch=@save_optimizer_switch;
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
flush table lineitem;
|
||||||
|
set use_stat_tables='never';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24;
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24 ;
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24;
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 1 2.6477
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and
|
||||||
|
index_name in ('i_l_shipdate', 'i_l_receiptdate');
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_shipdate);
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and index_name= 'i_l_shipdate';
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
set debug_sync='statistics_collection_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_shipdate);
|
||||||
|
set debug_sync='statistics_collection_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_receiptdate);
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 1 2.6477
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
DROP DATABASE dbt3_s001;
|
DROP DATABASE dbt3_s001;
|
||||||
use test;
|
use test;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -361,6 +361,178 @@ and o_orderkey=l_orderkey and p_partkey=l_partkey;
|
|||||||
o_orderkey p_partkey
|
o_orderkey p_partkey
|
||||||
5895 200
|
5895 200
|
||||||
set optimizer_switch=@save_optimizer_switch;
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
flush table lineitem;
|
||||||
|
set use_stat_tables='never';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24;
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24 ;
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24;
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
revenue
|
||||||
|
77949.91860000002
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 2 1.0364
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_partkey 2 1.0089
|
||||||
|
dbt3_s001 lineitem i_l_partkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 2 1.0152
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 1 2.6477
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 2 1.0149
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 2 1.2073
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 4 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 3 1.0030
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and
|
||||||
|
index_name in ('i_l_shipdate', 'i_l_receiptdate');
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 2 1.0364
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_partkey 2 1.0089
|
||||||
|
dbt3_s001 lineitem i_l_partkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 2 1.2073
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 3 1.0030
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 4 1.0000
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_shipdate);
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 2 1.0364
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_partkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_partkey 2 1.0089
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 2 1.0149
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 2 1.2073
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 3 1.0030
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 4 1.0000
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and index_name= 'i_l_shipdate';
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 2 1.0364
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_partkey 2 1.0089
|
||||||
|
dbt3_s001 lineitem i_l_partkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 2 1.2073
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 3 1.0030
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 4 1.0000
|
||||||
|
set debug_sync='statistics_collection_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_shipdate);
|
||||||
|
set debug_sync='statistics_collection_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_receiptdate);
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
db_name table_name index_name prefix_arity avg_frequency
|
||||||
|
dbt3_s001 lineitem PRIMARY 1 4.0033
|
||||||
|
dbt3_s001 lineitem PRIMARY 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 2 1.0364
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 1 2.7160
|
||||||
|
dbt3_s001 lineitem i_l_commitdate 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey 2 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 1 4.0033
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 2 1.0404
|
||||||
|
dbt3_s001 lineitem i_l_orderkey_quantity 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_partkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_partkey 2 1.0089
|
||||||
|
dbt3_s001 lineitem i_l_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_receiptdate 1 2.6477
|
||||||
|
dbt3_s001 lineitem i_l_shipdate 1 2.6500
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 3 1.0000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 2 1.2073
|
||||||
|
dbt3_s001 lineitem i_l_suppkey 1 600.5000
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 3 1.0030
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 2 8.5786
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 1 30.0250
|
||||||
|
dbt3_s001 lineitem i_l_suppkey_partkey 4 1.0000
|
||||||
DROP DATABASE dbt3_s001;
|
DROP DATABASE dbt3_s001;
|
||||||
use test;
|
use test;
|
||||||
set use_stat_tables=@save_use_stat_tables;
|
set use_stat_tables=@save_use_stat_tables;
|
||||||
|
@ -144,6 +144,115 @@ eval $QQ1;
|
|||||||
|
|
||||||
set optimizer_switch=@save_optimizer_switch;
|
set optimizer_switch=@save_optimizer_switch;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for parallel memory allocation for statistical data
|
||||||
|
#
|
||||||
|
# assumes that start the code of memory allocation for stats data has this line:
|
||||||
|
#
|
||||||
|
# DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
|
||||||
|
# DEBUG_SYNC(thd, "statistics_mem_alloc-start2");
|
||||||
|
#
|
||||||
|
|
||||||
|
let $Q6=
|
||||||
|
select sum(l_extendedprice*l_discount) as revenue
|
||||||
|
from lineitem
|
||||||
|
where l_shipdate >= date '1994-01-01'
|
||||||
|
and l_shipdate < date '1994-01-01' + interval '1' year
|
||||||
|
and l_discount between 0.06 - 0.01 and 0.06 + 0.01
|
||||||
|
and l_quantity < 24;
|
||||||
|
|
||||||
|
flush table lineitem;
|
||||||
|
set use_stat_tables='never';
|
||||||
|
eval $Q6;
|
||||||
|
|
||||||
|
connect (con1, localhost, root,,);
|
||||||
|
connect (con2, localhost, root,,);
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
--send_eval $Q6
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
set debug_sync='statistics_mem_alloc_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_mem_alloc_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
--send_eval $Q6
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
--reap
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
--reap
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
disconnect con1;
|
||||||
|
disconnect con2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for parallel statistics collection
|
||||||
|
#
|
||||||
|
# assumes that start of stats collection code has this line:
|
||||||
|
#
|
||||||
|
# DEBUG_SYNC(thd, "statistics_collection_start1");
|
||||||
|
# DEBUG_SYNC(thd, "statistics_collection_start2");
|
||||||
|
#
|
||||||
|
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and
|
||||||
|
index_name in ('i_l_shipdate', 'i_l_receiptdate');
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
--disable_result_log
|
||||||
|
--disable_warnings
|
||||||
|
analyze table lineitem persistent for columns() indexes (i_l_shipdate);
|
||||||
|
--enable_warnings
|
||||||
|
--enable_result_log
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
delete from mysql.index_stat
|
||||||
|
where table_name='lineitem' and index_name= 'i_l_shipdate';
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
|
||||||
|
connect (con1, localhost, root,,);
|
||||||
|
connect (con2, localhost, root,,);
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
set debug_sync='statistics_collection_start1 WAIT_FOR second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 SIGNAL first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
--send analyze table lineitem persistent for columns() indexes (i_l_shipdate)
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
set debug_sync='statistics_collection_start1 SIGNAL second_thread_started_too';
|
||||||
|
set debug_sync='statistics_collection_start2 WAIT_FOR first_thread_working';
|
||||||
|
use dbt3_s001;
|
||||||
|
set use_stat_tables='preferably';
|
||||||
|
--send analyze table lineitem persistent for columns() indexes (i_l_receiptdate)
|
||||||
|
|
||||||
|
connection con1;
|
||||||
|
--disable_result_log
|
||||||
|
--disable_warnings
|
||||||
|
--reap
|
||||||
|
--enable_warnings
|
||||||
|
--enable_result_log
|
||||||
|
|
||||||
|
connection con2;
|
||||||
|
--disable_result_log
|
||||||
|
--disable_warnings
|
||||||
|
--reap
|
||||||
|
--enable_warnings
|
||||||
|
--enable_result_log
|
||||||
|
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
disconnect con2;
|
||||||
|
|
||||||
|
select * from mysql.index_stat where table_name='lineitem' order by index_name;
|
||||||
|
|
||||||
DROP DATABASE dbt3_s001;
|
DROP DATABASE dbt3_s001;
|
||||||
|
|
||||||
|
137
sql/field.cc
137
sql/field.cc
@ -1180,11 +1180,11 @@ int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length,
|
|||||||
if (str == int_end || error == MY_ERRNO_EDOM)
|
if (str == int_end || error == MY_ERRNO_EDOM)
|
||||||
{
|
{
|
||||||
ErrConvString err(str, length, cs);
|
ErrConvString err(str, length, cs);
|
||||||
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(get_thd(), MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||||
"integer", err.ptr(), field_name,
|
"integer", err.ptr(), field_name,
|
||||||
(ulong) table->in_use->warning_info->current_row_for_warning());
|
(ulong) get_thd()->warning_info->current_row_for_warning());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Test if we have garbage at the end of the given string. */
|
/* Test if we have garbage at the end of the given string. */
|
||||||
@ -1253,7 +1253,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
|
|||||||
goto out_of_range;
|
goto out_of_range;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (table->in_use->count_cuted_fields &&
|
if (get_thd()->count_cuted_fields &&
|
||||||
check_int(cs, from, len, end, error))
|
check_int(cs, from, len, end, error))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -1319,12 +1319,14 @@ String *Field::val_int_as_str(String *val_buffer, bool unsigned_val)
|
|||||||
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
Field::Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
|
||||||
uchar null_bit_arg,
|
uchar null_bit_arg,
|
||||||
utype unireg_check_arg, const char *field_name_arg)
|
utype unireg_check_arg, const char *field_name_arg)
|
||||||
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0),
|
:ptr(ptr_arg), null_ptr(null_ptr_arg), table(0), orig_table(0), thd(0),
|
||||||
table_name(0), field_name(field_name_arg), option_list(0),
|
table_name(0), field_name(field_name_arg), option_list(0),
|
||||||
option_struct(0), key_start(0), part_of_key(0),
|
option_struct(0), key_start(0), part_of_key(0),
|
||||||
part_of_key_not_clustered(0), part_of_sortkey(0),
|
part_of_key_not_clustered(0), part_of_sortkey(0),
|
||||||
unireg_check(unireg_check_arg), field_length(length_arg),
|
unireg_check(unireg_check_arg), field_length(length_arg),
|
||||||
null_bit(null_bit_arg), is_created_from_null_item(FALSE), vcol_info(0),
|
null_bit(null_bit_arg), is_created_from_null_item(FALSE),
|
||||||
|
read_stats(NULL), collected_stats(0),
|
||||||
|
vcol_info(0),
|
||||||
stored_in_db(TRUE)
|
stored_in_db(TRUE)
|
||||||
{
|
{
|
||||||
flags=null_ptr ? 0: NOT_NULL_FLAG;
|
flags=null_ptr ? 0: NOT_NULL_FLAG;
|
||||||
@ -1431,10 +1433,11 @@ int Field::store(const char *to, uint length, CHARSET_INFO *cs,
|
|||||||
enum_check_fields check_level)
|
enum_check_fields check_level)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
enum_check_fields old_check_level= table->in_use->count_cuted_fields;
|
THD *thd= get_thd();
|
||||||
table->in_use->count_cuted_fields= check_level;
|
enum_check_fields old_check_level= thd->count_cuted_fields;
|
||||||
|
thd->count_cuted_fields= check_level;
|
||||||
res= store(to, length, cs);
|
res= store(to, length, cs);
|
||||||
table->in_use->count_cuted_fields= old_check_level;
|
thd->count_cuted_fields= old_check_level;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1871,6 +1874,18 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field *Field::clone(THD *thd_arg, MEM_ROOT *root, my_ptrdiff_t diff)
|
||||||
|
{
|
||||||
|
Field *tmp;
|
||||||
|
if ((tmp= (Field*) memdup_root(root,(char*) this,size_of())))
|
||||||
|
{
|
||||||
|
tmp->thd= thd_arg;
|
||||||
|
tmp->move_field_offset(diff);
|
||||||
|
}
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Field_null, a field that always return NULL
|
Field_null, a field that always return NULL
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -1985,7 +2000,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||||||
uchar *left_wall,*right_wall;
|
uchar *left_wall,*right_wall;
|
||||||
uchar tmp_char;
|
uchar tmp_char;
|
||||||
/*
|
/*
|
||||||
To remember if table->in_use->cuted_fields has already been incremented,
|
To remember if get_thd()->cuted_fields has already been incremented,
|
||||||
to do that only once
|
to do that only once
|
||||||
*/
|
*/
|
||||||
bool is_cuted_fields_incr=0;
|
bool is_cuted_fields_incr=0;
|
||||||
@ -2076,7 +2091,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||||||
it makes the code easer to read.
|
it makes the code easer to read.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (table->in_use->count_cuted_fields)
|
if (get_thd()->count_cuted_fields)
|
||||||
{
|
{
|
||||||
// Skip end spaces
|
// Skip end spaces
|
||||||
for (;from != end && my_isspace(&my_charset_bin, *from); from++) ;
|
for (;from != end && my_isspace(&my_charset_bin, *from); from++) ;
|
||||||
@ -2228,7 +2243,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Write digits of the frac_% parts ;
|
Write digits of the frac_% parts ;
|
||||||
Depending on table->in_use->count_cutted_fields, we may also want
|
Depending on get_thd()->count_cutted_fields, we may also want
|
||||||
to know if some non-zero tail of these parts will
|
to know if some non-zero tail of these parts will
|
||||||
be truncated (for example, 0.002->0.00 will generate a warning,
|
be truncated (for example, 0.002->0.00 will generate a warning,
|
||||||
while 0.000->0.00 will not)
|
while 0.000->0.00 will not)
|
||||||
@ -2246,7 +2261,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
if (pos == right_wall)
|
if (pos == right_wall)
|
||||||
{
|
{
|
||||||
if (table->in_use->count_cuted_fields && !is_cuted_fields_incr)
|
if (get_thd()->count_cuted_fields && !is_cuted_fields_incr)
|
||||||
break; // Go on below to see if we lose non zero digits
|
break; // Go on below to see if we lose non zero digits
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2667,20 +2682,21 @@ int Field_new_decimal::store(const char *from, uint length,
|
|||||||
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
||||||
int err;
|
int err;
|
||||||
my_decimal decimal_value;
|
my_decimal decimal_value;
|
||||||
|
THD *thd= get_thd();
|
||||||
DBUG_ENTER("Field_new_decimal::store(char*)");
|
DBUG_ENTER("Field_new_decimal::store(char*)");
|
||||||
|
|
||||||
if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
|
if ((err= str2my_decimal(E_DEC_FATAL_ERROR &
|
||||||
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
|
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
|
||||||
from, length, charset_arg,
|
from, length, charset_arg,
|
||||||
&decimal_value)) &&
|
&decimal_value)) &&
|
||||||
table->in_use->abort_on_warning)
|
thd->abort_on_warning)
|
||||||
{
|
{
|
||||||
ErrConvString errmsg(from, length, &my_charset_bin);
|
ErrConvString errmsg(from, length, &my_charset_bin);
|
||||||
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||||
"decimal", errmsg.ptr(), field_name,
|
"decimal", errmsg.ptr(), field_name,
|
||||||
(ulong) table->in_use->warning_info->current_row_for_warning());
|
(ulong) thd->warning_info->current_row_for_warning());
|
||||||
|
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
@ -2696,11 +2712,11 @@ int Field_new_decimal::store(const char *from, uint length,
|
|||||||
case E_DEC_BAD_NUM:
|
case E_DEC_BAD_NUM:
|
||||||
{
|
{
|
||||||
ErrConvString errmsg(from, length, &my_charset_bin);
|
ErrConvString errmsg(from, length, &my_charset_bin);
|
||||||
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||||
"decimal", errmsg.ptr(), field_name,
|
"decimal", errmsg.ptr(), field_name,
|
||||||
(ulong) table->in_use->warning_info->
|
(ulong) thd->warning_info->
|
||||||
current_row_for_warning());
|
current_row_for_warning());
|
||||||
my_decimal_set_zero(&decimal_value);
|
my_decimal_set_zero(&decimal_value);
|
||||||
break;
|
break;
|
||||||
@ -2728,6 +2744,7 @@ int Field_new_decimal::store(double nr)
|
|||||||
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
||||||
my_decimal decimal_value;
|
my_decimal decimal_value;
|
||||||
int err;
|
int err;
|
||||||
|
THD *thd= get_thd();
|
||||||
DBUG_ENTER("Field_new_decimal::store(double)");
|
DBUG_ENTER("Field_new_decimal::store(double)");
|
||||||
|
|
||||||
err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
|
err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
|
||||||
@ -2737,11 +2754,11 @@ int Field_new_decimal::store(double nr)
|
|||||||
if (check_overflow(err))
|
if (check_overflow(err))
|
||||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||||
/* Only issue a warning if store_value doesn't issue an warning */
|
/* Only issue a warning if store_value doesn't issue an warning */
|
||||||
table->in_use->got_warning= 0;
|
thd->got_warning= 0;
|
||||||
}
|
}
|
||||||
if (store_value(&decimal_value))
|
if (store_value(&decimal_value))
|
||||||
err= 1;
|
err= 1;
|
||||||
else if (err && !table->in_use->got_warning)
|
else if (err && !thd->got_warning)
|
||||||
err= warn_if_overflow(err);
|
err= warn_if_overflow(err);
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(err);
|
||||||
}
|
}
|
||||||
@ -2759,11 +2776,11 @@ int Field_new_decimal::store(longlong nr, bool unsigned_val)
|
|||||||
if (check_overflow(err))
|
if (check_overflow(err))
|
||||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||||
/* Only issue a warning if store_value doesn't issue an warning */
|
/* Only issue a warning if store_value doesn't issue an warning */
|
||||||
table->in_use->got_warning= 0;
|
get_thd()->got_warning= 0;
|
||||||
}
|
}
|
||||||
if (store_value(&decimal_value))
|
if (store_value(&decimal_value))
|
||||||
err= 1;
|
err= 1;
|
||||||
else if (err && !table->in_use->got_warning)
|
else if (err && !thd->got_warning)
|
||||||
err= warn_if_overflow(err);
|
err= warn_if_overflow(err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -3659,7 +3676,7 @@ longlong Field_long::val_int(void)
|
|||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
int32 j;
|
int32 j;
|
||||||
/* See the comment in Field_long::store(long long) */
|
/* See the comment in Field_long::store(long long) */
|
||||||
DBUG_ASSERT(table->in_use == current_thd);
|
DBUG_ASSERT(!table || table->in_use == current_thd);
|
||||||
j=sint4korr(ptr);
|
j=sint4korr(ptr);
|
||||||
return unsigned_flag ? (longlong) (uint32) j : (longlong) j;
|
return unsigned_flag ? (longlong) (uint32) j : (longlong) j;
|
||||||
}
|
}
|
||||||
@ -3741,7 +3758,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
error= 1;
|
error= 1;
|
||||||
}
|
}
|
||||||
else if (table->in_use->count_cuted_fields &&
|
else if (get_thd()->count_cuted_fields &&
|
||||||
check_int(cs, from, len, end, error))
|
check_int(cs, from, len, end, error))
|
||||||
error= 1;
|
error= 1;
|
||||||
else
|
else
|
||||||
@ -3893,7 +3910,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
char *end;
|
char *end;
|
||||||
double nr= my_strntod(cs,(char*) from,len,&end,&error);
|
double nr= my_strntod(cs,(char*) from,len,&end,&error);
|
||||||
if (error || (!len || ((uint) (end-from) != len &&
|
if (error || (!len || ((uint) (end-from) != len &&
|
||||||
table->in_use->count_cuted_fields)))
|
get_thd()->count_cuted_fields)))
|
||||||
{
|
{
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
||||||
@ -4081,7 +4098,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
char *end;
|
char *end;
|
||||||
double nr= my_strntod(cs,(char*) from, len, &end, &error);
|
double nr= my_strntod(cs,(char*) from, len, &end, &error);
|
||||||
if (error || (!len || ((uint) (end-from) != len &&
|
if (error || (!len || ((uint) (end-from) != len &&
|
||||||
table->in_use->count_cuted_fields)))
|
get_thd()->count_cuted_fields)))
|
||||||
{
|
{
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
(error ? ER_WARN_DATA_OUT_OF_RANGE : WARN_DATA_TRUNCATED), 1);
|
||||||
@ -4529,10 +4546,11 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
|
|||||||
|
|
||||||
int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
|
int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec)
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
|
||||||
int unused;
|
int unused;
|
||||||
MYSQL_TIME l_time= *ltime;
|
MYSQL_TIME l_time= *ltime;
|
||||||
ErrConvTime str(ltime);
|
ErrConvTime str(ltime);
|
||||||
|
THD *thd= get_thd();
|
||||||
|
|
||||||
bool valid= !check_date(&l_time, pack_time(&l_time) != 0,
|
bool valid= !check_date(&l_time, pack_time(&l_time) != 0,
|
||||||
(thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
|
(thd->variables.sql_mode & MODE_NO_ZERO_DATE) |
|
||||||
MODE_NO_ZERO_IN_DATE, &unused);
|
MODE_NO_ZERO_IN_DATE, &unused);
|
||||||
@ -4547,7 +4565,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
int error;
|
int error;
|
||||||
int have_smth_to_conv;
|
int have_smth_to_conv;
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
|
|
||||||
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
||||||
have_smth_to_conv= (str_to_datetime(cs, from, len, &l_time,
|
have_smth_to_conv= (str_to_datetime(cs, from, len, &l_time,
|
||||||
@ -4564,7 +4582,7 @@ int Field_timestamp::store(double nr)
|
|||||||
MYSQL_TIME l_time;
|
MYSQL_TIME l_time;
|
||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
|
|
||||||
longlong tmp= double_to_datetime(nr, &l_time, (thd->variables.sql_mode &
|
longlong tmp= double_to_datetime(nr, &l_time, (thd->variables.sql_mode &
|
||||||
MODE_NO_ZERO_DATE) |
|
MODE_NO_ZERO_DATE) |
|
||||||
@ -4578,7 +4596,7 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
|
|||||||
MYSQL_TIME l_time;
|
MYSQL_TIME l_time;
|
||||||
int error;
|
int error;
|
||||||
ErrConvInteger str(nr);
|
ErrConvInteger str(nr);
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
|
|
||||||
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
/* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
|
||||||
longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode &
|
longlong tmp= number_to_datetime(nr, 0, &l_time, (thd->variables.sql_mode &
|
||||||
@ -4670,7 +4688,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
|
|||||||
|
|
||||||
bool Field_timestamp::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
bool Field_timestamp::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
thd->time_zone_used= 1;
|
thd->time_zone_used= 1;
|
||||||
ulong sec_part;
|
ulong sec_part;
|
||||||
my_time_t temp= get_timestamp(&sec_part);
|
my_time_t temp= get_timestamp(&sec_part);
|
||||||
@ -4723,7 +4741,7 @@ void Field_timestamp::sql_type(String &res) const
|
|||||||
|
|
||||||
int Field_timestamp::set_time()
|
int Field_timestamp::set_time()
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
set_notnull();
|
set_notnull();
|
||||||
store_TIME(thd->query_start(), 0);
|
store_TIME(thd->query_start(), 0);
|
||||||
return 0;
|
return 0;
|
||||||
@ -4872,7 +4890,7 @@ int Field_timestamp_hires::store_decimal(const my_decimal *d)
|
|||||||
int error;
|
int error;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
longlong tmp;
|
longlong tmp;
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
|
|
||||||
if (my_decimal2seconds(d, &nr, &sec_part))
|
if (my_decimal2seconds(d, &nr, &sec_part))
|
||||||
@ -4890,7 +4908,7 @@ int Field_timestamp_hires::store_decimal(const my_decimal *d)
|
|||||||
|
|
||||||
int Field_timestamp_hires::set_time()
|
int Field_timestamp_hires::set_time()
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
set_notnull();
|
set_notnull();
|
||||||
store_TIME(thd->query_start(), thd->query_start_sec_part());
|
store_TIME(thd->query_start(), thd->query_start_sec_part());
|
||||||
return 0;
|
return 0;
|
||||||
@ -5009,7 +5027,7 @@ int Field_temporal::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
int error;
|
int error;
|
||||||
enum enum_mysql_timestamp_type func_res;
|
enum enum_mysql_timestamp_type func_res;
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
ErrConvString str(from, len, cs);
|
ErrConvString str(from, len, cs);
|
||||||
|
|
||||||
func_res= str_to_datetime(cs, from, len, <ime,
|
func_res= str_to_datetime(cs, from, len, <ime,
|
||||||
@ -5026,7 +5044,7 @@ int Field_temporal::store(double nr)
|
|||||||
{
|
{
|
||||||
int error= 0;
|
int error= 0;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
|
|
||||||
longlong tmp= double_to_datetime(nr, <ime,
|
longlong tmp= double_to_datetime(nr, <ime,
|
||||||
@ -5044,7 +5062,7 @@ int Field_temporal::store(longlong nr, bool unsigned_val)
|
|||||||
int error;
|
int error;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
longlong tmp;
|
longlong tmp;
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
ErrConvInteger str(nr);
|
ErrConvInteger str(nr);
|
||||||
|
|
||||||
tmp= number_to_datetime(nr, 0, <ime, (TIME_FUZZY_DATE |
|
tmp= number_to_datetime(nr, 0, <ime, (TIME_FUZZY_DATE |
|
||||||
@ -5109,7 +5127,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
int was_cut;
|
int was_cut;
|
||||||
int have_smth_to_conv=
|
int have_smth_to_conv=
|
||||||
str_to_time(cs, from, len, <ime,
|
str_to_time(cs, from, len, <ime,
|
||||||
table->in_use->variables.sql_mode &
|
get_thd()->variables.sql_mode &
|
||||||
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
|
(MODE_NO_ZERO_DATE | MODE_NO_ZERO_IN_DATE |
|
||||||
MODE_INVALID_DATES),
|
MODE_INVALID_DATES),
|
||||||
&was_cut) > MYSQL_TIMESTAMP_ERROR;
|
&was_cut) > MYSQL_TIMESTAMP_ERROR;
|
||||||
@ -5215,7 +5233,7 @@ String *Field_time::val_str(String *val_buffer,
|
|||||||
|
|
||||||
bool Field_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
bool Field_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY)))
|
if (!(fuzzydate & (TIME_FUZZY_DATE|TIME_TIME_ONLY)))
|
||||||
{
|
{
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
@ -5405,7 +5423,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
|
|||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (table->in_use->count_cuted_fields &&
|
if (get_thd()->count_cuted_fields &&
|
||||||
(error= check_int(cs, from, len, end, error)))
|
(error= check_int(cs, from, len, end, error)))
|
||||||
{
|
{
|
||||||
if (error == 1) /* empty or incorrect string */
|
if (error == 1) /* empty or incorrect string */
|
||||||
@ -5865,7 +5883,7 @@ int Field_datetime_hires::store_decimal(const my_decimal *d)
|
|||||||
int error;
|
int error;
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
longlong tmp;
|
longlong tmp;
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
|
|
||||||
if (my_decimal2seconds(d, &nr, &sec_part))
|
if (my_decimal2seconds(d, &nr, &sec_part))
|
||||||
@ -6002,7 +6020,9 @@ check_string_copy_error(Field_str *field,
|
|||||||
{
|
{
|
||||||
const char *pos;
|
const char *pos;
|
||||||
char tmp[32];
|
char tmp[32];
|
||||||
THD *thd= field->table->in_use;
|
THD *thd;
|
||||||
|
|
||||||
|
thd= field->get_thd();
|
||||||
|
|
||||||
if (!(pos= well_formed_error_pos) &&
|
if (!(pos= well_formed_error_pos) &&
|
||||||
!(pos= cannot_convert_error_pos))
|
!(pos= cannot_convert_error_pos))
|
||||||
@ -6044,11 +6064,12 @@ int
|
|||||||
Field_longstr::report_if_important_data(const char *pstr, const char *end,
|
Field_longstr::report_if_important_data(const char *pstr, const char *end,
|
||||||
bool count_spaces)
|
bool count_spaces)
|
||||||
{
|
{
|
||||||
if ((pstr < end) && table->in_use->count_cuted_fields)
|
THD *thd= get_thd();
|
||||||
|
if ((pstr < end) && thd->count_cuted_fields)
|
||||||
{
|
{
|
||||||
if (test_if_important_data(field_charset, pstr, end))
|
if (test_if_important_data(field_charset, pstr, end))
|
||||||
{
|
{
|
||||||
if (table->in_use->abort_on_warning)
|
if (thd->abort_on_warning)
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||||
else
|
else
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||||
@ -6075,7 +6096,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
const char *from_end_pos;
|
const char *from_end_pos;
|
||||||
|
|
||||||
/* See the comment for Field_long::store(long long) */
|
/* See the comment for Field_long::store(long long) */
|
||||||
DBUG_ASSERT(table->in_use == current_thd);
|
DBUG_ASSERT(!table || table->in_use == current_thd);
|
||||||
|
|
||||||
copy_length= well_formed_copy_nchars(field_charset,
|
copy_length= well_formed_copy_nchars(field_charset,
|
||||||
(char*) ptr, field_length,
|
(char*) ptr, field_length,
|
||||||
@ -6121,7 +6142,7 @@ int Field_str::store(double nr)
|
|||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
if (table->in_use->abort_on_warning)
|
if (get_thd()->abort_on_warning)
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||||
else
|
else
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||||
@ -6181,7 +6202,7 @@ double Field_string::val_real(void)
|
|||||||
double result;
|
double result;
|
||||||
|
|
||||||
result= my_strntod(cs,(char*) ptr,field_length,&end,&error);
|
result= my_strntod(cs,(char*) ptr,field_length,&end,&error);
|
||||||
if (!table->in_use->no_errors &&
|
if (!get_thd()->no_errors &&
|
||||||
(error || (field_length != (uint32)(end - (char*) ptr) &&
|
(error || (field_length != (uint32)(end - (char*) ptr) &&
|
||||||
!check_if_only_end_space(cs, end,
|
!check_if_only_end_space(cs, end,
|
||||||
(char*) ptr + field_length))))
|
(char*) ptr + field_length))))
|
||||||
@ -6205,7 +6226,7 @@ longlong Field_string::val_int(void)
|
|||||||
longlong result;
|
longlong result;
|
||||||
|
|
||||||
result= my_strntoll(cs, (char*) ptr,field_length,10,&end,&error);
|
result= my_strntoll(cs, (char*) ptr,field_length,10,&end,&error);
|
||||||
if (!table->in_use->no_errors &&
|
if (!get_thd()->no_errors &&
|
||||||
(error || (field_length != (uint32)(end - (char*) ptr) &&
|
(error || (field_length != (uint32)(end - (char*) ptr) &&
|
||||||
!check_if_only_end_space(cs, end,
|
!check_if_only_end_space(cs, end,
|
||||||
(char*) ptr + field_length))))
|
(char*) ptr + field_length))))
|
||||||
@ -6225,9 +6246,9 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)),
|
|||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
/* See the comment for Field_long::store(long long) */
|
/* See the comment for Field_long::store(long long) */
|
||||||
DBUG_ASSERT(table->in_use == current_thd);
|
DBUG_ASSERT(!table || table->in_use == current_thd);
|
||||||
uint length;
|
uint length;
|
||||||
if (table->in_use->variables.sql_mode &
|
if (get_thd()->variables.sql_mode &
|
||||||
MODE_PAD_CHAR_TO_FULL_LENGTH)
|
MODE_PAD_CHAR_TO_FULL_LENGTH)
|
||||||
length= my_charpos(field_charset, ptr, ptr + field_length,
|
length= my_charpos(field_charset, ptr, ptr + field_length,
|
||||||
field_length / field_charset->mbmaxlen);
|
field_length / field_charset->mbmaxlen);
|
||||||
@ -6244,7 +6265,7 @@ my_decimal *Field_string::val_decimal(my_decimal *decimal_value)
|
|||||||
ASSERT_COLUMN_MARKED_FOR_READ;
|
ASSERT_COLUMN_MARKED_FOR_READ;
|
||||||
int err= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr, field_length,
|
int err= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr, field_length,
|
||||||
charset(), decimal_value);
|
charset(), decimal_value);
|
||||||
if (!table->in_use->no_errors && err)
|
if (!get_thd()->no_errors && err)
|
||||||
{
|
{
|
||||||
ErrConvString errmsg((char*) ptr, field_length, charset());
|
ErrConvString errmsg((char*) ptr, field_length, charset());
|
||||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
@ -6628,7 +6649,7 @@ double Field_varstring::val_real(void)
|
|||||||
uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
|
uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
|
||||||
result= my_strntod(cs, (char*)ptr+length_bytes, length, &end, &error);
|
result= my_strntod(cs, (char*)ptr+length_bytes, length, &end, &error);
|
||||||
|
|
||||||
if (!table->in_use->no_errors &&
|
if (!get_thd()->no_errors &&
|
||||||
(error || (length != (uint)(end - (char*)ptr+length_bytes) &&
|
(error || (length != (uint)(end - (char*)ptr+length_bytes) &&
|
||||||
!check_if_only_end_space(cs, end, (char*)ptr+length_bytes+length))))
|
!check_if_only_end_space(cs, end, (char*)ptr+length_bytes+length))))
|
||||||
{
|
{
|
||||||
@ -6651,7 +6672,7 @@ longlong Field_varstring::val_int(void)
|
|||||||
longlong result= my_strntoll(cs, (char*) ptr+length_bytes, length, 10,
|
longlong result= my_strntoll(cs, (char*) ptr+length_bytes, length, 10,
|
||||||
&end, &error);
|
&end, &error);
|
||||||
|
|
||||||
if (!table->in_use->no_errors &&
|
if (!get_thd()->no_errors &&
|
||||||
(error || (length != (uint)(end - (char*)ptr+length_bytes) &&
|
(error || (length != (uint)(end - (char*)ptr+length_bytes) &&
|
||||||
!check_if_only_end_space(cs, end, (char*)ptr+length_bytes+length))))
|
!check_if_only_end_space(cs, end, (char*)ptr+length_bytes+length))))
|
||||||
{
|
{
|
||||||
@ -6680,7 +6701,7 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
|
|||||||
int error= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
|
int error= str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
|
||||||
cs, decimal_value);
|
cs, decimal_value);
|
||||||
|
|
||||||
if (!table->in_use->no_errors && error)
|
if (!get_thd()->no_errors && error)
|
||||||
{
|
{
|
||||||
push_numerical_conversion_warning(current_thd, (char*)ptr+length_bytes,
|
push_numerical_conversion_warning(current_thd, (char*)ptr+length_bytes,
|
||||||
length, cs, "DECIMAL",
|
length, cs, "DECIMAL",
|
||||||
@ -7661,7 +7682,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||||||
tmp=0;
|
tmp=0;
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||||
}
|
}
|
||||||
if (!table->in_use->count_cuted_fields)
|
if (!get_thd()->count_cuted_fields)
|
||||||
err= 0;
|
err= 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -7685,7 +7706,7 @@ int Field_enum::store(longlong nr, bool unsigned_val)
|
|||||||
if ((ulonglong) nr > typelib->count || nr == 0)
|
if ((ulonglong) nr > typelib->count || nr == 0)
|
||||||
{
|
{
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||||
if (nr != 0 || table->in_use->count_cuted_fields)
|
if (nr != 0 || get_thd()->count_cuted_fields)
|
||||||
{
|
{
|
||||||
nr= 0;
|
nr= 0;
|
||||||
error= 1;
|
error= 1;
|
||||||
@ -8215,7 +8236,7 @@ int Field_bit::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len);
|
set_rec_bits((1 << bit_len) - 1, bit_ptr, bit_ofs, bit_len);
|
||||||
memset(ptr, 0xff, bytes_in_rec);
|
memset(ptr, 0xff, bytes_in_rec);
|
||||||
if (table->in_use->really_abort_on_warning())
|
if (get_thd()->really_abort_on_warning())
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||||
else
|
else
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
@ -8650,7 +8671,7 @@ int Field_bit_as_char::store(const char *from, uint length, CHARSET_INFO *cs)
|
|||||||
memset(ptr, 0xff, bytes_in_rec);
|
memset(ptr, 0xff, bytes_in_rec);
|
||||||
if (bits)
|
if (bits)
|
||||||
*ptr&= ((1 << bits) - 1); /* set first uchar */
|
*ptr&= ((1 << bits) - 1); /* set first uchar */
|
||||||
if (table->in_use->really_abort_on_warning())
|
if (get_thd()->really_abort_on_warning())
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_DATA_TOO_LONG, 1);
|
||||||
else
|
else
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
@ -9752,7 +9773,7 @@ void Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level,
|
|||||||
uint code, const ErrConv *str,
|
uint code, const ErrConv *str,
|
||||||
timestamp_type ts_type, int cuted_increment)
|
timestamp_type ts_type, int cuted_increment)
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= get_thd();
|
||||||
if (thd->really_abort_on_warning() && level >= MYSQL_ERROR::WARN_LEVEL_WARN)
|
if (thd->really_abort_on_warning() && level >= MYSQL_ERROR::WARN_LEVEL_WARN)
|
||||||
make_truncated_value_warning(thd, level, str, ts_type, field_name);
|
make_truncated_value_warning(thd, level, str, ts_type, field_name);
|
||||||
else
|
else
|
||||||
|
83
sql/field.h
83
sql/field.h
@ -36,6 +36,8 @@ class Protocol;
|
|||||||
class Create_field;
|
class Create_field;
|
||||||
class Relay_log_info;
|
class Relay_log_info;
|
||||||
class Field;
|
class Field;
|
||||||
|
class Column_statistics;
|
||||||
|
class Column_statistics_collected;
|
||||||
|
|
||||||
enum enum_check_fields
|
enum enum_check_fields
|
||||||
{
|
{
|
||||||
@ -173,6 +175,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
TABLE *table; // Pointer for table
|
TABLE *table; // Pointer for table
|
||||||
TABLE *orig_table; // Pointer to original table
|
TABLE *orig_table; // Pointer to original table
|
||||||
|
THD *thd; // Used when table == NULL
|
||||||
const char * const *table_name;
|
const char * const *table_name;
|
||||||
const char *field_name;
|
const char *field_name;
|
||||||
/** reference to the list of options or NULL */
|
/** reference to the list of options or NULL */
|
||||||
@ -220,89 +223,16 @@ public:
|
|||||||
|
|
||||||
bool is_stat_field; /* TRUE in Field objects created for column min/max values */
|
bool is_stat_field; /* TRUE in Field objects created for column min/max values */
|
||||||
|
|
||||||
/* Statistical data on a column */
|
|
||||||
class Column_statistics
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static const uint Scale_factor_nulls_ratio= 100000;
|
|
||||||
static const uint Scale_factor_avg_length= 100000;
|
|
||||||
static const uint Scale_factor_avg_frequency= 100000;
|
|
||||||
public:
|
|
||||||
/*
|
|
||||||
Bitmap indicating what statistical characteristics
|
|
||||||
are available for the column
|
|
||||||
*/
|
|
||||||
uint32 column_stat_nulls;
|
|
||||||
|
|
||||||
/* Minimum value for the column */
|
|
||||||
Field *min_value;
|
|
||||||
/* Maximum value for the column */
|
|
||||||
Field *max_value;
|
|
||||||
private:
|
|
||||||
/*
|
|
||||||
The ratio Z/N multiplied by the scale factor Scale_factor_nulls_ratio,
|
|
||||||
where N is the total number of rows,
|
|
||||||
Z is the number of nulls in the column
|
|
||||||
*/
|
|
||||||
ulong nulls_ratio;
|
|
||||||
/*
|
|
||||||
Average number of bytes occupied by the representation of a
|
|
||||||
value of the column in memory buffers such as join buffer
|
|
||||||
multiplied by the scale factor Scale_factor_avg_length
|
|
||||||
CHAR values are stripped of trailing spaces
|
|
||||||
Flexible values are stripped of their length prefixes.
|
|
||||||
*/
|
|
||||||
ulong avg_length;
|
|
||||||
/*
|
|
||||||
The ratio N/D multiplied by the scale factor Scale_factor_avg_frequency,
|
|
||||||
where N is the number of rows with null value
|
|
||||||
in the column, D the number of distinct values among them
|
|
||||||
*/
|
|
||||||
ulong avg_frequency;
|
|
||||||
|
|
||||||
public:
|
|
||||||
double get_nulls_ratio()
|
|
||||||
{
|
|
||||||
return (double) nulls_ratio / Scale_factor_nulls_ratio;
|
|
||||||
}
|
|
||||||
double get_avg_length()
|
|
||||||
{
|
|
||||||
return (double) avg_length / Scale_factor_avg_length;
|
|
||||||
}
|
|
||||||
double get_avg_frequency()
|
|
||||||
{
|
|
||||||
return (double) avg_frequency / Scale_factor_avg_frequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_nulls_ratio (double val)
|
|
||||||
{
|
|
||||||
nulls_ratio= (ulong) (val * Scale_factor_nulls_ratio);
|
|
||||||
}
|
|
||||||
void set_avg_length (double val)
|
|
||||||
{
|
|
||||||
avg_length= (ulong) (val * Scale_factor_avg_length);
|
|
||||||
}
|
|
||||||
void set_avg_frequency (double val)
|
|
||||||
{
|
|
||||||
avg_frequency= (ulong) (val * Scale_factor_avg_frequency);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This structure is used for statistical data on the column
|
This structure is used for statistical data on the column
|
||||||
that has been read from the statistical table column_stat
|
that has been read from the statistical table column_stat
|
||||||
*/
|
*/
|
||||||
Column_statistics read_stat;
|
Column_statistics *read_stats;
|
||||||
/*
|
/*
|
||||||
This structure is used for statistical data on the column that
|
This structure is used for statistical data on the column that
|
||||||
is collected by the function collect_statistics_for_table
|
is collected by the function collect_statistics_for_table
|
||||||
*/
|
*/
|
||||||
Column_statistics write_stat;
|
Column_statistics_collected *collected_stats;
|
||||||
|
|
||||||
/* These members are used only when collecting statistics on the column */
|
|
||||||
ha_rows nulls;
|
|
||||||
ulonglong column_total_length;
|
|
||||||
Count_distinct_field *count_distinct;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is additional data provided for any computed(virtual) field.
|
This is additional data provided for any computed(virtual) field.
|
||||||
@ -522,6 +452,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline bool real_maybe_null(void) { return null_ptr != 0; }
|
inline bool real_maybe_null(void) { return null_ptr != 0; }
|
||||||
|
|
||||||
|
inline THD *get_thd() { return table ? table->in_use : thd; }
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
LAST_NULL_BYTE_UNDEF= 0
|
LAST_NULL_BYTE_UNDEF= 0
|
||||||
};
|
};
|
||||||
@ -560,6 +492,7 @@ public:
|
|||||||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
|
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
|
||||||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
|
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
|
||||||
bool stat_flag= FALSE);
|
bool stat_flag= FALSE);
|
||||||
|
Field *clone(THD *thd_arg, MEM_ROOT *mem_root, my_ptrdiff_t diff);
|
||||||
inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
|
inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
|
||||||
{
|
{
|
||||||
ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
|
ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
|
||||||
|
@ -484,6 +484,7 @@ ulong refresh_version; /* Increments on each reload */
|
|||||||
query_id_t global_query_id;
|
query_id_t global_query_id;
|
||||||
my_atomic_rwlock_t global_query_id_lock;
|
my_atomic_rwlock_t global_query_id_lock;
|
||||||
my_atomic_rwlock_t thread_running_lock;
|
my_atomic_rwlock_t thread_running_lock;
|
||||||
|
my_atomic_rwlock_t statistics_lock;
|
||||||
ulong aborted_threads, aborted_connects;
|
ulong aborted_threads, aborted_connects;
|
||||||
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
|
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
|
||||||
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
|
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
|
||||||
@ -1852,6 +1853,7 @@ void clean_up(bool print_message)
|
|||||||
sys_var_end();
|
sys_var_end();
|
||||||
my_atomic_rwlock_destroy(&global_query_id_lock);
|
my_atomic_rwlock_destroy(&global_query_id_lock);
|
||||||
my_atomic_rwlock_destroy(&thread_running_lock);
|
my_atomic_rwlock_destroy(&thread_running_lock);
|
||||||
|
my_atomic_rwlock_destroy(&statistics_lock);
|
||||||
mysql_mutex_lock(&LOCK_thread_count);
|
mysql_mutex_lock(&LOCK_thread_count);
|
||||||
DBUG_PRINT("quit", ("got thread count lock"));
|
DBUG_PRINT("quit", ("got thread count lock"));
|
||||||
ready_to_exit=1;
|
ready_to_exit=1;
|
||||||
@ -7275,6 +7277,7 @@ static int mysql_init_variables(void)
|
|||||||
global_query_id= thread_id= 1L;
|
global_query_id= thread_id= 1L;
|
||||||
my_atomic_rwlock_init(&global_query_id_lock);
|
my_atomic_rwlock_init(&global_query_id_lock);
|
||||||
my_atomic_rwlock_init(&thread_running_lock);
|
my_atomic_rwlock_init(&thread_running_lock);
|
||||||
|
my_atomic_rwlock_init(&statistics_lock);
|
||||||
strmov(server_version, MYSQL_SERVER_VERSION);
|
strmov(server_version, MYSQL_SERVER_VERSION);
|
||||||
threads.empty();
|
threads.empty();
|
||||||
thread_cache.empty();
|
thread_cache.empty();
|
||||||
|
@ -712,6 +712,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
|||||||
thd->variables.use_stat_tables > 0)
|
thd->variables.use_stat_tables > 0)
|
||||||
{
|
{
|
||||||
if (!(compl_result_code=
|
if (!(compl_result_code=
|
||||||
|
alloc_statistics_for_table(thd, table->table)) &&
|
||||||
|
!(compl_result_code=
|
||||||
collect_statistics_for_table(thd, table->table)))
|
collect_statistics_for_table(thd, table->table)))
|
||||||
compl_result_code= update_statistics_for_table(thd, table->table);
|
compl_result_code= update_statistics_for_table(thd, table->table);
|
||||||
}
|
}
|
||||||
|
@ -3138,6 +3138,16 @@ retry_share:
|
|||||||
while (table_cache_count > table_cache_size && unused_tables)
|
while (table_cache_count > table_cache_size && unused_tables)
|
||||||
free_cache_entry(unused_tables);
|
free_cache_entry(unused_tables);
|
||||||
|
|
||||||
|
if (thd->variables.use_stat_tables > 0)
|
||||||
|
{
|
||||||
|
if (share->table_category != TABLE_CATEGORY_SYSTEM)
|
||||||
|
{
|
||||||
|
if (!share->stats_can_be_read &&
|
||||||
|
!alloc_statistics_for_table_share(thd, share, TRUE))
|
||||||
|
share->stats_can_be_read= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mysql_mutex_unlock(&LOCK_open);
|
mysql_mutex_unlock(&LOCK_open);
|
||||||
|
|
||||||
/* make a new table */
|
/* make a new table */
|
||||||
@ -4632,11 +4642,21 @@ open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *tables,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thd->variables.use_stat_tables > 0)
|
if (thd->variables.use_stat_tables > 0 && tables->table)
|
||||||
|
{
|
||||||
|
TABLE_SHARE *table_share= tables->table->s;
|
||||||
|
if (table_share && table_share->table_category != TABLE_CATEGORY_SYSTEM)
|
||||||
|
{
|
||||||
|
if (!table_share->stats_can_be_read &&
|
||||||
|
!alloc_statistics_for_table_share(thd, table_share, FALSE))
|
||||||
|
table_share->stats_can_be_read= TRUE;
|
||||||
|
|
||||||
|
if (table_share->stats_can_be_read && !table_share->stats_is_read)
|
||||||
{
|
{
|
||||||
if (tables->table && tables->table->s &&
|
|
||||||
tables->table->s->table_category != TABLE_CATEGORY_SYSTEM)
|
|
||||||
(void) read_statistics_for_table(thd, tables->table);
|
(void) read_statistics_for_table(thd, tables->table);
|
||||||
|
table_share->stats_is_read= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_view_routines:
|
process_view_routines:
|
||||||
|
@ -314,6 +314,9 @@ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived);
|
|||||||
|
|
||||||
int read_statistics_for_table(THD *thd, TABLE *table);
|
int read_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int collect_statistics_for_table(THD *thd, TABLE *table);
|
int collect_statistics_for_table(THD *thd, TABLE *table);
|
||||||
|
int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share,
|
||||||
|
bool is_safe);
|
||||||
|
int alloc_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int update_statistics_for_table(THD *thd, TABLE *table);
|
int update_statistics_for_table(THD *thd, TABLE *table);
|
||||||
int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab);
|
int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab);
|
||||||
int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col);
|
int delete_statistics_for_column(THD *thd, TABLE *tab, Field *col);
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "opt_subselect.h"
|
#include "opt_subselect.h"
|
||||||
#include "log_slow.h"
|
#include "log_slow.h"
|
||||||
#include "sql_derived.h"
|
#include "sql_derived.h"
|
||||||
|
#include "sql_statistics.h"
|
||||||
|
|
||||||
#include "debug_sync.h" // DEBUG_SYNC
|
#include "debug_sync.h" // DEBUG_SYNC
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
@ -14252,7 +14253,6 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
table->intersect_keys.init();
|
table->intersect_keys.init();
|
||||||
table->keys_in_use_for_query.init();
|
table->keys_in_use_for_query.init();
|
||||||
table->no_rows_with_nulls= param->force_not_null_cols;
|
table->no_rows_with_nulls= param->force_not_null_cols;
|
||||||
table->read_stat.cardinality_is_null= TRUE;
|
|
||||||
|
|
||||||
table->s= share;
|
table->s= share;
|
||||||
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
|
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
|
||||||
@ -14690,8 +14690,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
keyinfo->ext_key_parts= keyinfo->key_parts;
|
keyinfo->ext_key_parts= keyinfo->key_parts;
|
||||||
keyinfo->key_length=0;
|
keyinfo->key_length=0;
|
||||||
keyinfo->rec_per_key=NULL;
|
keyinfo->rec_per_key=NULL;
|
||||||
keyinfo->read_stat.init_avg_frequency(NULL);
|
keyinfo->read_stats= NULL;
|
||||||
keyinfo->write_stat.init_avg_frequency(NULL);
|
keyinfo->collected_stats= NULL;
|
||||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||||
keyinfo->is_statistics_from_stat_tables= FALSE;
|
keyinfo->is_statistics_from_stat_tables= FALSE;
|
||||||
keyinfo->name= (char*) "group_key";
|
keyinfo->name= (char*) "group_key";
|
||||||
@ -14808,7 +14808,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
|||||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||||
keyinfo->is_statistics_from_stat_tables= FALSE;
|
keyinfo->is_statistics_from_stat_tables= FALSE;
|
||||||
keyinfo->rec_per_key=0;
|
keyinfo->rec_per_key=0;
|
||||||
keyinfo->read_stat.init_avg_frequency(NULL);
|
keyinfo->read_stats= NULL;
|
||||||
|
keyinfo->collected_stats= NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create an extra field to hold NULL bits so that unique indexes on
|
Create an extra field to hold NULL bits so that unique indexes on
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,4 +60,159 @@ enum enum_index_stat_col
|
|||||||
INDEX_STAT_AVG_FREQUENCY
|
INDEX_STAT_AVG_FREQUENCY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Columns_statistics;
|
||||||
|
class Index_statistics;
|
||||||
|
|
||||||
|
|
||||||
|
/* Statistical data on a table */
|
||||||
|
|
||||||
|
class Table_statistics
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
my_bool cardinality_is_null; /* TRUE if the cardinality is unknown */
|
||||||
|
ha_rows cardinality; /* Number of rows in the table */
|
||||||
|
Column_statistics *column_stats; /* Array of statistical data for columns */
|
||||||
|
Index_statistics *index_stats; /* Array of statistical data for indexes */
|
||||||
|
ulong *idx_avg_frequency; /* Array of records per key for index prefixes */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Statistical data on a column */
|
||||||
|
|
||||||
|
class Column_statistics
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint Scale_factor_nulls_ratio= 100000;
|
||||||
|
static const uint Scale_factor_avg_length= 100000;
|
||||||
|
static const uint Scale_factor_avg_frequency= 100000;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/*
|
||||||
|
Bitmap indicating what statistical characteristics
|
||||||
|
are available for the column
|
||||||
|
*/
|
||||||
|
uint32 column_stat_nulls;
|
||||||
|
|
||||||
|
/* Minimum value for the column */
|
||||||
|
Field *min_value;
|
||||||
|
/* Maximum value for the column */
|
||||||
|
Field *max_value;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/*
|
||||||
|
The ratio Z/N multiplied by the scale factor Scale_factor_nulls_ratio,
|
||||||
|
where
|
||||||
|
N is the total number of rows,
|
||||||
|
Z is the number of nulls in the column
|
||||||
|
*/
|
||||||
|
ulong nulls_ratio;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Average number of bytes occupied by the representation of a
|
||||||
|
value of the column in memory buffers such as join buffer
|
||||||
|
multiplied by the scale factor Scale_factor_avg_length.
|
||||||
|
CHAR values are stripped of trailing spaces.
|
||||||
|
Flexible values are stripped of their length prefixes.
|
||||||
|
*/
|
||||||
|
ulong avg_length;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The ratio N/D multiplied by the scale factor Scale_factor_avg_frequency,
|
||||||
|
where
|
||||||
|
N is the number of rows with not null value in the column,
|
||||||
|
D the number of distinct values among them
|
||||||
|
*/
|
||||||
|
ulong avg_frequency;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void set_all_nulls()
|
||||||
|
{
|
||||||
|
column_stat_nulls=
|
||||||
|
((1 << (COLUMN_STAT_AVG_FREQUENCY-COLUMN_STAT_COLUMN_NAME))-1) <<
|
||||||
|
(COLUMN_STAT_COLUMN_NAME+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_not_null(uint stat_field_no)
|
||||||
|
{
|
||||||
|
column_stat_nulls&= ~(1 << stat_field_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null(uint stat_field_no)
|
||||||
|
{
|
||||||
|
return test(column_stat_nulls & (1 << stat_field_no));
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_nulls_ratio()
|
||||||
|
{
|
||||||
|
return (double) nulls_ratio / Scale_factor_nulls_ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_avg_length()
|
||||||
|
{
|
||||||
|
return (double) avg_length / Scale_factor_avg_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_avg_frequency()
|
||||||
|
{
|
||||||
|
return (double) avg_frequency / Scale_factor_avg_frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_nulls_ratio (double val)
|
||||||
|
{
|
||||||
|
nulls_ratio= (ulong) (val * Scale_factor_nulls_ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_avg_length (double val)
|
||||||
|
{
|
||||||
|
avg_length= (ulong) (val * Scale_factor_avg_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_avg_frequency (double val)
|
||||||
|
{
|
||||||
|
avg_frequency= (ulong) (val * Scale_factor_avg_frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Statistical data on an index prefixes */
|
||||||
|
|
||||||
|
class Index_statistics
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint Scale_factor_avg_frequency= 100000;
|
||||||
|
/*
|
||||||
|
The k-th element of this array contains the ratio N/D
|
||||||
|
multiplied by the scale factor Scale_factor_avg_frequency,
|
||||||
|
where N is the number of index entries without nulls
|
||||||
|
in the first k components, and D is the number of distinct
|
||||||
|
k-component prefixes among them
|
||||||
|
*/
|
||||||
|
ulong *avg_frequency;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void init_avg_frequency(ulong *ptr) { avg_frequency= ptr; }
|
||||||
|
|
||||||
|
bool avg_frequency_is_inited() { return avg_frequency != NULL; }
|
||||||
|
|
||||||
|
double get_avg_frequency(uint i)
|
||||||
|
{
|
||||||
|
return (double) avg_frequency[i] / Scale_factor_avg_frequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_avg_frequency(uint i, double val)
|
||||||
|
{
|
||||||
|
avg_frequency[i]= (ulong) (val * Scale_factor_avg_frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* SQL_STATISTICS_H */
|
#endif /* SQL_STATISTICS_H */
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
struct TABLE;
|
struct TABLE;
|
||||||
class Field;
|
class Field;
|
||||||
|
class Index_statistics;
|
||||||
|
|
||||||
class THD;
|
class THD;
|
||||||
|
|
||||||
@ -121,43 +122,16 @@ typedef struct st_key {
|
|||||||
*/
|
*/
|
||||||
ulong *rec_per_key;
|
ulong *rec_per_key;
|
||||||
|
|
||||||
/* Statistical data on an index prefixes */
|
|
||||||
class Index_statistics
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static const uint Scale_factor_avg_frequency= 100000;
|
|
||||||
/*
|
|
||||||
The k-th element of this array contains the ratio N/D
|
|
||||||
multiplied by the scale factor Scale_factor_avg_frequency,
|
|
||||||
where N is the number of index entries without nulls
|
|
||||||
in the first k components, and D is the number of distinct
|
|
||||||
k-component prefixes among them
|
|
||||||
*/
|
|
||||||
ulong *avg_frequency;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void init_avg_frequency(ulong *ptr) { avg_frequency= ptr; }
|
|
||||||
bool avg_frequency_is_set() { return avg_frequency != NULL; }
|
|
||||||
double get_avg_frequency(uint i)
|
|
||||||
{
|
|
||||||
return (double) avg_frequency[i] / Scale_factor_avg_frequency;
|
|
||||||
}
|
|
||||||
void set_avg_frequency(uint i, double val)
|
|
||||||
{
|
|
||||||
avg_frequency[i]= (ulong) (val * Scale_factor_avg_frequency);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This structure is used for statistical data on the index
|
This structure is used for statistical data on the index
|
||||||
that has been read from the statistical table index_stat
|
that has been read from the statistical table index_stat
|
||||||
*/
|
*/
|
||||||
Index_statistics read_stat;
|
Index_statistics *read_stats;
|
||||||
/*
|
/*
|
||||||
This structure is used for statistical data on the index that
|
This structure is used for statistical data on the index that
|
||||||
is collected by the function collect_statistics_for_table
|
is collected by the function collect_statistics_for_table
|
||||||
*/
|
*/
|
||||||
Index_statistics write_stat;
|
Index_statistics *collected_stats;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int bdb_return_if_eq;
|
int bdb_return_if_eq;
|
||||||
@ -168,13 +142,8 @@ typedef struct st_key {
|
|||||||
engine_option_value *option_list;
|
engine_option_value *option_list;
|
||||||
ha_index_option_struct *option_struct; /* structure with parsed options */
|
ha_index_option_struct *option_struct; /* structure with parsed options */
|
||||||
|
|
||||||
inline double real_rec_per_key(uint i)
|
double real_rec_per_key(uint i);
|
||||||
{
|
|
||||||
if (rec_per_key == 0)
|
|
||||||
return 0;
|
|
||||||
return (is_statistics_from_stat_tables ?
|
|
||||||
read_stat.get_avg_frequency(i) : (double) rec_per_key[i]);
|
|
||||||
}
|
|
||||||
} KEY;
|
} KEY;
|
||||||
|
|
||||||
|
|
||||||
|
30
sql/table.cc
30
sql/table.cc
@ -39,6 +39,7 @@
|
|||||||
#include "my_bit.h"
|
#include "my_bit.h"
|
||||||
#include "sql_select.h"
|
#include "sql_select.h"
|
||||||
#include "sql_derived.h"
|
#include "sql_derived.h"
|
||||||
|
#include "sql_statistics.h"
|
||||||
#include "mdl.h" // MDL_wait_for_graph_visitor
|
#include "mdl.h" // MDL_wait_for_graph_visitor
|
||||||
|
|
||||||
/* INFORMATION_SCHEMA name */
|
/* INFORMATION_SCHEMA name */
|
||||||
@ -762,8 +763,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
ulong pos, record_offset;
|
ulong pos, record_offset;
|
||||||
ulong *rec_per_key= NULL;
|
ulong *rec_per_key= NULL;
|
||||||
ulong rec_buff_length;
|
ulong rec_buff_length;
|
||||||
ulong *read_avg_frequency= NULL;
|
|
||||||
ulong *write_avg_frequency= NULL;
|
|
||||||
handler *handler_file= 0;
|
handler *handler_file= 0;
|
||||||
KEY *keyinfo;
|
KEY *keyinfo;
|
||||||
KEY_PART_INFO *key_part= NULL;
|
KEY_PART_INFO *key_part= NULL;
|
||||||
@ -946,14 +945,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
|
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
|
||||||
sizeof(ulong) * ext_key_parts)))
|
sizeof(ulong) * ext_key_parts)))
|
||||||
goto err;
|
goto err;
|
||||||
if (!(read_avg_frequency= (ulong*) alloc_root(&share->mem_root,
|
|
||||||
sizeof(double) *
|
|
||||||
ext_key_parts)))
|
|
||||||
goto err;
|
|
||||||
if (!(write_avg_frequency= (ulong*) alloc_root(&share->mem_root,
|
|
||||||
sizeof(double) *
|
|
||||||
ext_key_parts)))
|
|
||||||
goto err;
|
|
||||||
first_key_part= key_part;
|
first_key_part= key_part;
|
||||||
first_key_parts= first_keyinfo.key_parts;
|
first_key_parts= first_keyinfo.key_parts;
|
||||||
keyinfo->flags= first_keyinfo.flags;
|
keyinfo->flags= first_keyinfo.flags;
|
||||||
@ -966,13 +957,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
|
|
||||||
keyinfo->key_part= key_part;
|
keyinfo->key_part= key_part;
|
||||||
keyinfo->rec_per_key= rec_per_key;
|
keyinfo->rec_per_key= rec_per_key;
|
||||||
keyinfo->read_stat.init_avg_frequency(read_avg_frequency);
|
|
||||||
keyinfo->write_stat.init_avg_frequency(write_avg_frequency);
|
|
||||||
for (j=keyinfo->key_parts ; j-- ; key_part++)
|
for (j=keyinfo->key_parts ; j-- ; key_part++)
|
||||||
{
|
{
|
||||||
*rec_per_key++=0;
|
*rec_per_key++=0;
|
||||||
*read_avg_frequency++= 0;
|
|
||||||
*write_avg_frequency++= 0;
|
|
||||||
key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
|
key_part->fieldnr= (uint16) (uint2korr(strpos) & FIELD_NR_MASK);
|
||||||
key_part->offset= (uint) uint2korr(strpos+2)-1;
|
key_part->offset= (uint) uint2korr(strpos+2)-1;
|
||||||
key_part->key_type= (uint) uint2korr(strpos+5);
|
key_part->key_type= (uint) uint2korr(strpos+5);
|
||||||
@ -1019,8 +1006,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
|
|||||||
{
|
{
|
||||||
*key_part++= first_key_part[j];
|
*key_part++= first_key_part[j];
|
||||||
*rec_per_key++= 0;
|
*rec_per_key++= 0;
|
||||||
*read_avg_frequency++= 0;
|
|
||||||
*write_avg_frequency++= 0;
|
|
||||||
keyinfo->ext_key_parts++;
|
keyinfo->ext_key_parts++;
|
||||||
keyinfo->ext_key_part_map|= 1 << j;
|
keyinfo->ext_key_part_map|= 1 << j;
|
||||||
}
|
}
|
||||||
@ -2416,8 +2401,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
outparam->read_stat.cardinality_is_null= TRUE;
|
|
||||||
|
|
||||||
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
|
if (!(field_ptr = (Field **) alloc_root(&outparam->mem_root,
|
||||||
(uint) ((share->fields+1)*
|
(uint) ((share->fields+1)*
|
||||||
sizeof(Field*)))))
|
sizeof(Field*)))))
|
||||||
@ -5965,7 +5948,8 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
|
|||||||
if (!keyinfo->rec_per_key)
|
if (!keyinfo->rec_per_key)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
|
bzero(keyinfo->rec_per_key, sizeof(ulong)*key_parts);
|
||||||
keyinfo->read_stat.init_avg_frequency(NULL);
|
keyinfo->read_stats= NULL;
|
||||||
|
keyinfo->collected_stats= NULL;
|
||||||
|
|
||||||
for (i= 0; i < key_parts; i++)
|
for (i= 0; i < key_parts; i++)
|
||||||
{
|
{
|
||||||
@ -6753,6 +6737,14 @@ uint TABLE_SHARE::actual_n_key_parts(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double KEY::real_rec_per_key(uint i)
|
||||||
|
{
|
||||||
|
if (rec_per_key == 0)
|
||||||
|
return 0;
|
||||||
|
return (is_statistics_from_stat_tables ?
|
||||||
|
read_stats->get_avg_frequency(i) : (double) rec_per_key[i]);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Instansiate templates
|
** Instansiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
25
sql/table.h
25
sql/table.h
@ -45,6 +45,7 @@ struct TABLE_LIST;
|
|||||||
class ACL_internal_schema_access;
|
class ACL_internal_schema_access;
|
||||||
class ACL_internal_table_access;
|
class ACL_internal_table_access;
|
||||||
class Field;
|
class Field;
|
||||||
|
class Table_statistics;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Used to identify NESTED_JOIN structures within a join (applicable only to
|
Used to identify NESTED_JOIN structures within a join (applicable only to
|
||||||
@ -577,6 +578,15 @@ struct TABLE_SHARE
|
|||||||
KEY *key_info; /* data of keys in database */
|
KEY *key_info; /* data of keys in database */
|
||||||
uint *blob_field; /* Index to blobs in Field arrray*/
|
uint *blob_field; /* Index to blobs in Field arrray*/
|
||||||
|
|
||||||
|
bool stats_can_be_read; /* Memory for statistical data is allocated */
|
||||||
|
bool stats_is_read; /* Statistical data for table has been read
|
||||||
|
from statistical tables */
|
||||||
|
/*
|
||||||
|
This structure is used for statistical data on the table
|
||||||
|
that has been read from the statistical table table_stat
|
||||||
|
*/
|
||||||
|
Table_statistics *read_stats;
|
||||||
|
|
||||||
uchar *default_values; /* row with default values */
|
uchar *default_values; /* row with default values */
|
||||||
LEX_STRING comment; /* Comment about table */
|
LEX_STRING comment; /* Comment about table */
|
||||||
CHARSET_INFO *table_charset; /* Default charset of string fields */
|
CHARSET_INFO *table_charset; /* Default charset of string fields */
|
||||||
@ -1007,24 +1017,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
query_id_t query_id;
|
query_id_t query_id;
|
||||||
|
|
||||||
/* Statistical data on a table */
|
|
||||||
class Table_statistics
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
my_bool cardinality_is_null; /* TRUE if the cardinality is unknown */
|
|
||||||
ha_rows cardinality; /* Number of rows in the table */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
This structure is used for statistical data on the table
|
|
||||||
that has been read from the statistical table table_stat
|
|
||||||
*/
|
|
||||||
Table_statistics read_stat;
|
|
||||||
/*
|
/*
|
||||||
This structure is used for statistical data on the table that
|
This structure is used for statistical data on the table that
|
||||||
is collected by the function collect_statistics_for_table
|
is collected by the function collect_statistics_for_table
|
||||||
*/
|
*/
|
||||||
Table_statistics write_stat;
|
Table_statistics *collected_stats;
|
||||||
|
|
||||||
/* The estimate of the number of records in the table used by optimizer */
|
/* The estimate of the number of records in the table used by optimizer */
|
||||||
ha_rows used_stat_records;
|
ha_rows used_stat_records;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user