From 46be0bdbf15034d1d8f161093ffb4fdc91a93c14 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Wed, 9 Jun 2021 20:39:50 +0100 Subject: [PATCH 1/9] Prepare JSON as valid histogram_type Signed-off-by: Michael Okoko --- scripts/mysql_system_tables.sql | 2 +- sql/item_strfunc.cc | 2 +- sql/sql_statistics.cc | 10 +++++++--- sql/sql_statistics.h | 12 +++++++++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index cee47a0e5d656..353f665844744 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -314,7 +314,7 @@ DROP TABLE tmp_proxies_priv; CREATE TABLE IF NOT EXISTS table_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, cardinality bigint(21) unsigned DEFAULT NULL, PRIMARY KEY (db_name,table_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Tables'; -CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varbinary(255) DEFAULT NULL, max_value varbinary(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB'), histogram varbinary(255), PRIMARY KEY (db_name,table_name,column_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; +CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varbinary(255) DEFAULT NULL, max_value varbinary(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON'), histogram varbinary(255), PRIMARY KEY (db_name,table_name,column_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; CREATE TABLE IF NOT EXISTS index_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, index_name varchar(64) NOT NULL, prefix_arity int(11) unsigned NOT NULL, avg_frequency decimal(12,4) DEFAULT NULL, PRIMARY KEY (db_name,table_name,index_name,prefix_arity) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Indexes'; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 7e8ff667e75a6..072d775dcaa7d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -496,7 +496,7 @@ String *Item_func_from_base64::val_str(String *str) const char *histogram_types[] = - {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", 0}; + {"SINGLE_PREC_HB", "DOUBLE_PREC_HB", "JSON", 0}; static TYPELIB hystorgam_types_typelib= { array_elements(histogram_types), "histogram_types", diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 1f034f490c8e2..5e78738c18419 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -178,7 +178,7 @@ TABLE_FIELD_TYPE column_stat_fields[COLUMN_STAT_N_FIELDS] = }, { { STRING_WITH_LEN("hist_type") }, - { STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB')") }, + { STRING_WITH_LEN("enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON')") }, { STRING_WITH_LEN("utf8mb3") } }, { @@ -1070,8 +1070,12 @@ class Column_stat: public Stat_table stat_field->store(stats->histogram.get_type() + 1); break; case COLUMN_STAT_HISTOGRAM: - stat_field->store((char *)stats->histogram.get_values(), - stats->histogram.get_size(), &my_charset_bin); + if (stats->histogram.get_type() == JSON) { + stat_field->store((char *) "hello_world", 11, &my_charset_bin); + } else { + stat_field->store((char *) stats->histogram.get_values(), + stats->histogram.get_size(), &my_charset_bin); + } break; } } diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 35b3aa33accf5..555d03cfa2232 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -42,7 +42,8 @@ typedef enum enum_histogram_type { SINGLE_PREC_HB, - DOUBLE_PREC_HB + DOUBLE_PREC_HB, + JSON } Histogram_type; enum enum_stat_tables @@ -154,6 +155,7 @@ class Histogram case SINGLE_PREC_HB: return ((uint) (1 << 8) - 1); case DOUBLE_PREC_HB: + case JSON: return ((uint) (1 << 16) - 1); } return 1; @@ -166,6 +168,7 @@ class Histogram case SINGLE_PREC_HB: return size; case DOUBLE_PREC_HB: + case JSON: return size / 2; } return 0; @@ -179,6 +182,7 @@ class Histogram case SINGLE_PREC_HB: return (uint) (((uint8 *) values)[i]); case DOUBLE_PREC_HB: + case JSON: return (uint) uint2korr(values + i * 2); } return 0; @@ -253,7 +257,8 @@ class Histogram void set_value(uint i, double val) { switch (type) { - case SINGLE_PREC_HB: + case SINGLE_PREC_HB: + case JSON: ((uint8 *) values)[i]= (uint8) (val * prec_factor()); return; case DOUBLE_PREC_HB: @@ -265,7 +270,8 @@ class Histogram void set_prev_value(uint i) { switch (type) { - case SINGLE_PREC_HB: + case SINGLE_PREC_HB: + case JSON: ((uint8 *) values)[i]= ((uint8 *) values)[i-1]; return; case DOUBLE_PREC_HB: From e31830ca9cfe43371e4b613e9a38e9065ad268f0 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Mon, 14 Jun 2021 17:14:11 +0100 Subject: [PATCH 2/9] add json statistics test and change histogram column type to blob --- mysql-test/main/statistics_json.test | 28 ++++++++++++++++++++++++++++ scripts/mysql_system_tables.sql | 2 +- sql/sql_statistics.cc | 5 +++-- 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 mysql-test/main/statistics_json.test diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test new file mode 100644 index 0000000000000..0af7d1f6d1d00 --- /dev/null +++ b/mysql-test/main/statistics_json.test @@ -0,0 +1,28 @@ +--source include/have_stat_tables.inc +--echo # +--echo # Test that JSON is a valid histogram type and we can store JSON strings in mysql.column_stats +--echo # +--disable_warnings +drop table if exists t1; +--enable_warnings + +set @save_histogram_type=@@histogram_type; + +CREATE TABLE t1 ( + a int NOT NULL PRIMARY KEY, + b varchar(32) +) ENGINE=MYISAM; + +SET histogram_type='JSON'; +SELECT @@histogram_type; + +INSERT INTO t1 VALUES + (7, 'xxxxxxxxxxxxxxxxxxxxxxxxxx'), + (17, 'vvvvvvvvvvvvv'); + +ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); +DESCRIBE mysql.column_stats; +SELECT * FROM mysql.column_stats; + +set histogram_type=@save_histogram_type; +DROP TABLE t1; \ No newline at end of file diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql index 353f665844744..e31f3372b5f7e 100644 --- a/scripts/mysql_system_tables.sql +++ b/scripts/mysql_system_tables.sql @@ -314,7 +314,7 @@ DROP TABLE tmp_proxies_priv; CREATE TABLE IF NOT EXISTS table_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, cardinality bigint(21) unsigned DEFAULT NULL, PRIMARY KEY (db_name,table_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Tables'; -CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varbinary(255) DEFAULT NULL, max_value varbinary(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON'), histogram varbinary(255), PRIMARY KEY (db_name,table_name,column_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; +CREATE TABLE IF NOT EXISTS column_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, column_name varchar(64) NOT NULL, min_value varbinary(255) DEFAULT NULL, max_value varbinary(255) DEFAULT NULL, nulls_ratio decimal(12,4) DEFAULT NULL, avg_length decimal(12,4) DEFAULT NULL, avg_frequency decimal(12,4) DEFAULT NULL, hist_size tinyint unsigned, hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON'), histogram blob, PRIMARY KEY (db_name,table_name,column_name) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Columns'; CREATE TABLE IF NOT EXISTS index_stats (db_name varchar(64) NOT NULL, table_name varchar(64) NOT NULL, index_name varchar(64) NOT NULL, prefix_arity int(11) unsigned NOT NULL, avg_frequency decimal(12,4) DEFAULT NULL, PRIMARY KEY (db_name,table_name,index_name,prefix_arity) ) engine=Aria transactional=0 CHARACTER SET utf8 COLLATE utf8_bin comment='Statistics on Indexes'; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 5e78738c18419..16e3e8b166474 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -183,7 +183,7 @@ TABLE_FIELD_TYPE column_stat_fields[COLUMN_STAT_N_FIELDS] = }, { { STRING_WITH_LEN("histogram") }, - { STRING_WITH_LEN("varbinary(255)") }, + { STRING_WITH_LEN("blob") }, { NULL, 0 } } }; @@ -1071,7 +1071,8 @@ class Column_stat: public Stat_table break; case COLUMN_STAT_HISTOGRAM: if (stats->histogram.get_type() == JSON) { - stat_field->store((char *) "hello_world", 11, &my_charset_bin); + const char* val = "{'hello': 'world'}"; + stat_field->store(val, strlen(val), &my_charset_bin); } else { stat_field->store((char *) stats->histogram.get_values(), stats->histogram.get_size(), &my_charset_bin); From 2951887af6cb05931e9640d399ca7fbf9c245961 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Wed, 16 Jun 2021 09:54:34 +0100 Subject: [PATCH 3/9] record statistics_json test Signed-off-by: Michael Okoko --- mysql-test/main/statistics_json.result | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 mysql-test/main/statistics_json.result diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result new file mode 100644 index 0000000000000..3e7d3a307fa02 --- /dev/null +++ b/mysql-test/main/statistics_json.result @@ -0,0 +1,38 @@ +# +# Test that JSON is a valid histogram type and we can store JSON strings in mysql.column_stats +# +drop table if exists t1; +set @save_histogram_type=@@histogram_type; +CREATE TABLE t1 ( +a int NOT NULL PRIMARY KEY, +b varchar(32) +) ENGINE=MYISAM; +SET histogram_type='JSON'; +SELECT @@histogram_type; +@@histogram_type +JSON +INSERT INTO t1 VALUES +(7, 'xxxxxxxxxxxxxxxxxxxxxxxxxx'), +(17, 'vvvvvvvvvvvvv'); +ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +DESCRIBE mysql.column_stats; +Field Type Null Key Default Extra +db_name varchar(64) NO PRI NULL +table_name varchar(64) NO PRI NULL +column_name varchar(64) NO PRI NULL +min_value varbinary(255) YES NULL +max_value varbinary(255) YES NULL +nulls_ratio decimal(12,4) YES NULL +avg_length decimal(12,4) YES NULL +avg_frequency decimal(12,4) YES NULL +hist_size tinyint(3) unsigned YES NULL +hist_type enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON') YES NULL +histogram blob YES NULL +SELECT * FROM mysql.column_stats; +db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram +test t1 b vvvvvvvvvvvvv xxxxxxxxxxxxxxxxxxxxxxxxxx 0.0000 19.5000 1.0000 254 JSON {'hello': 'world'} +set histogram_type=@save_histogram_type; +DROP TABLE t1; From f11a89e872e334779c5a5170d61421b64ce94236 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Tue, 22 Jun 2021 18:41:37 +0100 Subject: [PATCH 4/9] Update test results to match updated system tables Signed-off-by: Michael Okoko --- mysql-test/main/system_mysql_db.result | 4 ++-- mysql-test/main/system_mysql_db_fix40123.result | 4 ++-- mysql-test/main/system_mysql_db_fix50030.result | 4 ++-- mysql-test/main/system_mysql_db_fix50117.result | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/main/system_mysql_db.result b/mysql-test/main/system_mysql_db.result index d0d1e7c11757b..b756dfcf45e43 100644 --- a/mysql-test/main/system_mysql_db.result +++ b/mysql-test/main/system_mysql_db.result @@ -234,8 +234,8 @@ column_stats CREATE TABLE `column_stats` ( `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, `hist_size` tinyint(3) unsigned DEFAULT NULL, - `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') COLLATE utf8mb3_bin DEFAULT NULL, - `histogram` varbinary(255) DEFAULT NULL, + `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON') COLLATE utf8mb3_bin DEFAULT NULL, + `histogram` blob DEFAULT NULL, PRIMARY KEY (`db_name`,`table_name`,`column_name`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin PAGE_CHECKSUM=1 TRANSACTIONAL=0 COMMENT='Statistics on Columns' show create table index_stats; diff --git a/mysql-test/main/system_mysql_db_fix40123.result b/mysql-test/main/system_mysql_db_fix40123.result index 127e2c49642f5..ec972058d54e0 100644 --- a/mysql-test/main/system_mysql_db_fix40123.result +++ b/mysql-test/main/system_mysql_db_fix40123.result @@ -272,8 +272,8 @@ column_stats CREATE TABLE `column_stats` ( `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, `hist_size` tinyint(3) unsigned DEFAULT NULL, - `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') COLLATE utf8mb3_bin DEFAULT NULL, - `histogram` varbinary(255) DEFAULT NULL, + `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON') COLLATE utf8mb3_bin DEFAULT NULL, + `histogram` blob DEFAULT NULL, PRIMARY KEY (`db_name`,`table_name`,`column_name`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin PAGE_CHECKSUM=1 TRANSACTIONAL=0 COMMENT='Statistics on Columns' show create table index_stats; diff --git a/mysql-test/main/system_mysql_db_fix50030.result b/mysql-test/main/system_mysql_db_fix50030.result index fd0074c7f54f5..4e038849cf672 100644 --- a/mysql-test/main/system_mysql_db_fix50030.result +++ b/mysql-test/main/system_mysql_db_fix50030.result @@ -276,8 +276,8 @@ column_stats CREATE TABLE `column_stats` ( `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, `hist_size` tinyint(3) unsigned DEFAULT NULL, - `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') COLLATE utf8mb3_bin DEFAULT NULL, - `histogram` varbinary(255) DEFAULT NULL, + `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON') COLLATE utf8mb3_bin DEFAULT NULL, + `histogram` blob DEFAULT NULL, PRIMARY KEY (`db_name`,`table_name`,`column_name`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin PAGE_CHECKSUM=1 TRANSACTIONAL=0 COMMENT='Statistics on Columns' show create table index_stats; diff --git a/mysql-test/main/system_mysql_db_fix50117.result b/mysql-test/main/system_mysql_db_fix50117.result index a7d705c4158c1..7d540477d51ac 100644 --- a/mysql-test/main/system_mysql_db_fix50117.result +++ b/mysql-test/main/system_mysql_db_fix50117.result @@ -256,8 +256,8 @@ column_stats CREATE TABLE `column_stats` ( `avg_length` decimal(12,4) DEFAULT NULL, `avg_frequency` decimal(12,4) DEFAULT NULL, `hist_size` tinyint(3) unsigned DEFAULT NULL, - `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB') COLLATE utf8mb3_bin DEFAULT NULL, - `histogram` varbinary(255) DEFAULT NULL, + `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON') COLLATE utf8mb3_bin DEFAULT NULL, + `histogram` blob DEFAULT NULL, PRIMARY KEY (`db_name`,`table_name`,`column_name`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin PAGE_CHECKSUM=1 TRANSACTIONAL=0 COMMENT='Statistics on Columns' show create table index_stats; From 5fd0d1ec2962a65791e02f2e38dc0eb0e7f18aad Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Thu, 24 Jun 2021 07:41:09 +0100 Subject: [PATCH 5/9] rough base for json histogram builder Signed-off-by: Michael Okoko --- mysql-test/main/statistics_json.result | Bin 1365 -> 3493 bytes mysql-test/main/statistics_json.test | 6 ++ sql/sql_statistics.cc | 92 ++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 11 deletions(-) diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 3e7d3a307fa02f184d2c36efc35e5a060634c35f..3e7a9a43634820375c226f93045309fec268058c 100644 GIT binary patch literal 3493 zcmeHK&2HO95Ec>y!S2;PG&v38gUEt4EGJG82nH-m>qNCg8YG=W2?}B*u4Mw`%Hb{* zsh2)NpQ88PgWUTFeT2M4yStPnI+2rHf*?P0;Lmb)=jWUGcDac+A!I^=JfjkR4LlbT z0TiY*O=37pgq)0Xnt`03GoU<%mkdUfgBs6SsV`)n@Ueh|LpB#L(yh@XEixVnNu|J> zIL;^MAn7n=kemXWsWk=2MiUDrVPDWGiHB^~KnPQ$Dbn#8N@KB^!ux zn$CY`NMlk6MEE%2?B|5X?3}5K%B23HkV!@Y6n-fiNfuu<-8;e^614s90a*ii6CWll zjZvteL~fC$=!nfxhn>o$`qHY_+c#&E4pzA*Dk?7bb z?dZ`#-KlrH6V)}90aNRj{9d*j8m5zBb@fF<`~-)-*Ix_v1(X%Us=%!Bzshnomz9+1 z$5m!l30OtA^wU%(QiVN4)gGFnE4yxnwzsyGpvHr(U2`vAcXsa~oe=aK1Khc^*d6EH zA^h84pIH7}$c^hYBY)ql{qyRNTJ7I!<-5M>_aATFG~@dl<$YuE`StA|o@f_0YBy?c ztfza|3@O)2cnl}k)4X@$mFNUKGDVn`3%^8j7P^e940x^~Bg5|&NqQ2br zXjMF)t0^T2fA_R-S=uIL#;7S`w^~-*T$v t_K#T=D;j$Xtdgp>o$q%|+22kc8fH)WcH;eB-)rj|cYN=7`Lol+{{wRFJh=b> delta 46 zcmZ1~eU)ni7pqXUdPZtaPQJR8f_iy=QBI0_?PLx%Eq<3E{{V#$M<*Xwg%U$+E&x#^ B4Lkq< diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test index 0af7d1f6d1d00..9ffb27b621d78 100644 --- a/mysql-test/main/statistics_json.test +++ b/mysql-test/main/statistics_json.test @@ -25,4 +25,10 @@ DESCRIBE mysql.column_stats; SELECT * FROM mysql.column_stats; set histogram_type=@save_histogram_type; + +## Remove against Milestone-2 +ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); +SELECT * FROM mysql.column_stats; +select table_name, hist_type, decode_histogram(hist_type, histogram ) from mysql.column_stats; + DROP TABLE t1; \ No newline at end of file diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 16e3e8b166474..d2cad99f13022 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -32,6 +32,9 @@ #include "uniques.h" #include "sql_show.h" #include "sql_partition.h" +#include "my_json_writer.h" + +#include /* The system variable 'use_stat_tables' can take one of the @@ -1070,13 +1073,8 @@ class Column_stat: public Stat_table stat_field->store(stats->histogram.get_type() + 1); break; case COLUMN_STAT_HISTOGRAM: - if (stats->histogram.get_type() == JSON) { - const char* val = "{'hello': 'world'}"; - stat_field->store(val, strlen(val), &my_charset_bin); - } else { stat_field->store((char *) stats->histogram.get_values(), stats->histogram.get_size(), &my_charset_bin); - } break; } } @@ -1524,6 +1522,7 @@ class Stat_table_write_iter class Histogram_builder { +protected: Field *column; /* table field for which the histogram is built */ uint col_length; /* size of this field */ ha_rows records; /* number of records the histogram is built for */ @@ -1554,13 +1553,15 @@ class Histogram_builder count_distinct_single_occurence= 0; } + virtual ~Histogram_builder() = default; + ulonglong get_count_distinct() const { return count_distinct; } ulonglong get_count_single_occurence() const { return count_distinct_single_occurence; } - int next(void *elem, element_count elem_cnt) + virtual int next(void *elem, element_count elem_cnt) { count_distinct++; if (elem_cnt == 1) @@ -1572,7 +1573,7 @@ class Histogram_builder { column->store_field_value((uchar *) elem, col_length); histogram->set_value(curr_bucket, - column->pos_in_interval(min_value, max_value)); + column->pos_in_interval(min_value, max_value)); curr_bucket++; while (curr_bucket != hist_width && count > bucket_capacity * (curr_bucket + 1)) @@ -1585,6 +1586,57 @@ class Histogram_builder } }; +class Histogram_builder_json : public Histogram_builder +{ +std::vector bucket_bounds; + +public: + Histogram_builder_json(Field *col, uint col_len, ha_rows rows) + : Histogram_builder(col, col_len, rows) + { + Column_statistics *col_stats= col->collected_stats; + min_value= col_stats->min_value; + max_value= col_stats->max_value; + histogram= &col_stats->histogram; + hist_width= histogram->get_width(); + bucket_capacity= (double) records / (hist_width + 1); + curr_bucket= 0; + count= 0; + count_distinct= 0; + count_distinct_single_occurence= 0; + bucket_bounds = {}; + } + + ~Histogram_builder_json() override = default; + + int next(void *elem, element_count elem_cnt) override + { + count_distinct++; + if (elem_cnt == 1) + count_distinct_single_occurence++; + count+= elem_cnt; + if (curr_bucket == hist_width) + return 0; + if (count > bucket_capacity * (curr_bucket + 1)) + { + auto *val= new StringBuffer; + column->val_str(val); + bucket_bounds.emplace_back(String(val->ptr(), val->length(), &my_charset_bin)); + curr_bucket++; + } + return 0; + } + + void build() { + Json_writer *writer = new Json_writer(); + writer->start_array(); + for(auto& value: bucket_bounds) { + writer->add_str(value); + } + writer->end_array(); + histogram->set_values((uchar *) writer->output.get_string()->ptr()); + } +}; C_MODE_START @@ -1594,6 +1646,12 @@ int histogram_build_walk(void *elem, element_count elem_cnt, void *arg) return hist_builder->next(elem, elem_cnt); } +int json_histogram_build_walk(void *elem, element_count elem_cnt, void *arg) +{ + Histogram_builder_json *hist_builder= (Histogram_builder_json *) arg; + return hist_builder->next(elem, elem_cnt); +} + static int count_distinct_single_occurence_walk(void *elem, @@ -1699,10 +1757,22 @@ class Count_distinct_field: public Sql_alloc */ void walk_tree_with_histogram(ha_rows rows) { - Histogram_builder hist_builder(table_field, tree_key_length, rows); - tree->walk(table_field->table, histogram_build_walk, (void *) &hist_builder); - distincts= hist_builder.get_count_distinct(); - distincts_single_occurence= hist_builder.get_count_single_occurence(); + if(table_field->collected_stats->histogram.get_type() == JSON) + { + Histogram_builder_json hist_builder(table_field, tree_key_length, rows); + tree->walk(table_field->table, json_histogram_build_walk, + (void *) &hist_builder); + hist_builder.build(); + distincts= hist_builder.get_count_distinct(); + distincts_single_occurence= hist_builder.get_count_single_occurence(); + } else + { + Histogram_builder hist_builder(table_field, tree_key_length, rows); + tree->walk(table_field->table, histogram_build_walk, + (void *) &hist_builder); + distincts= hist_builder.get_count_distinct(); + distincts_single_occurence= hist_builder.get_count_single_occurence(); + } } ulonglong get_count_distinct() From 8850ba00a4fcf7735cfcba72dd5464a486a8e7e0 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Wed, 30 Jun 2021 05:51:08 +0100 Subject: [PATCH 6/9] Store bucket bounds and extend test cases for JSON histogram This fixes the memory allocation for json histogram builder and add more column types for testing. Some challenges at the moment include: * Garbage value at the end of JSON array still persists. * Garbage value also gets appended to bucket values if the column is a primary key. * There's a memory leak resulting in a "Warning: Memory not freed" message at the end of tests. Signed-off-by: Michael Okoko --- mysql-test/main/statistics_json.result | Bin 3493 -> 24466 bytes mysql-test/main/statistics_json.test | 56 +++++++++++++++++-------- sql/sql_statistics.cc | 21 +++++++--- sql/sql_statistics.h | 6 +-- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 3e7a9a43634820375c226f93045309fec268058c..a6b9458823ea055d35cedfc0ec6b5d77778b9b46 100644 GIT binary patch literal 24466 zcmeHP&2QVt6-N#QN*;<{dnhnT4oS9NgERbwkws)#b`(ppD#=NcATUPKSYnqV9e&tR z4&7}RJ@?vUi=sXC(nF8EY|z^lXzx9=i=z84^w>vo_#w;oVi!?FIpRT_H#401y^nb_ zdNbs0@iyu)KS05l2I!2T0dvasdrZ<_cp`< ziqlbYh=y(m_{4i#V!hR^b$Y1Y>K#N+cWaGWwTFE6a%1)f9eeI1$~wYFfqO*MEwNkc z<)TVBxf99YPJ%z@DMpT^EwR$7G@d>yfNj@0-FmlIYxU6XK?hYDjV-YkiB32;5t{xe zZZ%1;SAiIS`ZfbBP>0&n*G!0X5&A;S8Ceed&~k?Cgu#y!fL>_;g0}`f0=?O65U}B8 zk00y2(2pxw?v^CEped06X!cq3>>4xO<3cLEH24*M}BSsUvMvQD_Ue;D zP1E=^rwE>*5j?qE@?Q%cU4owHtNgB`Ti=#}dGNy-yD=_De_n>M6=8|%g9{!j zoYwf=oMY+RLIpO(;5ZJ$tw%hCWM^ zkvGm=RP4a7@LrL>oAq8*H*^ATiY{_t+?^C$!3N5F0VGprun{AO2RctiIFe*C0bR;% zq3sLZ%+(&G>JFJu*?uBCds2&BNbV{sohFK}L&pN2iMrrOnU9*5<9g^I4D6}pj8NUT zsWbGGn(zKMF|h4gV`ZQ=o~;VhYGrq2pdRe43{+V4#8>%;RjpHB6{z4HR|V=`b9-f= z9zI+pSeGfX3s>sz7b-@2m{e!|tj;ZPlx*0<~RPnPJt2kWhS; zf4S1F9Ig!1W@lxfK3$n%)oZp_MXHDUD`NnU>#G1&e38b7*7vmp-ZKgO_^#Luy<<9H z6^M00Bwc|3x-RJ|MA9LqI~&)NHOS%tS~Uu@^B}F3r)47w1t<9$&eIr6QG`1wfVQK? zc}tRM7AS-0(Iy0MS=ZIPOoj&Y7FCQ*J*%l>UCC>jvLxpe#zZ4|?^uI|@=_ujvY9hL z3|TGmBO6#zvu+f{G_@R`YUq-ZKdYOXWagEDXGJb@swoC8loOpOW>PM`NT#2q{)%n) zB($SVB}V`&ARv6zh<1f$g1Z=UZe?3OQTZ1K&kwo2R3Ni5ZH6)52 zr6mzPg34_bYjLBT(lCiwf#LK))(TNgtw5QYo>MUFjRK`h=8vN1*2}u(FJ*oy@*U1>pK!)f zwmUrV7L0Ci(|gFn8(GfIv-5T8JLl`vTRbY3J@u%4zD~3Dlf<60I_-x%?wjRw(vVe_ zbJ#8Pe&rx-clqWFJX@Sd6#}CpnkAx>3B_R&%|IkGaHs=ogLFQ`*pP{qQ8JOSkx?p< zO+BOFseE=MB$~R?GGf5oDW{Zd8ZgbJl%`8WirQQcljRSSn_w}_8^D<(I%3gj7Qr+( z&v{j8lOL6kHq$c_oBYrONfYuWKQ^Il^7AcbR$1TVM|NN}%L@%1Qs3ZMMJgyPwxWYc zmE+NvI&jE{I>Iw+(x?41HoIJ?cq8D+a_E&a$#M!4f3r=!J{`JCJA`l*?;N2U_-Ald z?W&r~D*Fb@g(X4c2;Bjw`0hSqHXJ;;x9pQAGqT_aU$em&b=V0Usk8<&6_!pU2x~U# zQu`DJi??({=K&-LcRlJ1*!i+@&%)sKw6EUI?!TlxkQf z2s`cs7U87=mZ>X2*rgMJ1T`mU!au&p!VXMRyxCr|t=FKKt_1KX_w!_jP7pVw-uxY4GM3fBmg>dcj=!_OgmQ zCdvF)wV4O&u;9a82JcbBN@r2meAjz$>;cyI;i7uX+MVyZ9?%muV4gLg2-YXvi1)1e z+f2-Ny&q14@Len;=eurN@b=%kSTW9beGn{0zH_>o@4Djx(;vTsAmx15-4oji<{&O0 zW4`M{+kZDfyP2-nJDa7Rp#WUv#@Cz=*yH>9ZPyFJQOMxU>$iOU?Tf}oSH8Btz{0*}2#x^{oCvf;Xl4ALua`KKck>BeX4l{5JpWmW9Iwu*Sty77q8A>y4~MoTDoX zhY+&1fx)+Fo+Z;^!=1p_T^DhcMTbq-qo)f|Vp%wBht5xF-&%kY%feyT9W7)wM5rtr z_NU48s5b literal 3493 zcmeHK&2HO95Ec>y!S2;PG&v38gUEt4EGJG82nH-m>qNCg8YG=W2?}B*u4Mw`%Hb{* zsh2)NpQ88PgWUTFeT2M4yStPnI+2rHf*?P0;Lmb)=jWUGcDac+A!I^=JfjkR4LlbT z0TiY*O=37pgq)0Xnt`03GoU<%mkdUfgBs6SsV`)n@Ueh|LpB#L(yh@XEixVnNu|J> zIL;^MAn7n=kemXWsWk=2MiUDrVPDWGiHB^~KnPQ$Dbn#8N@KB^!ux zn$CY`NMlk6MEE%2?B|5X?3}5K%B23HkV!@Y6n-fiNfuu<-8;e^614s90a*ii6CWll zjZvteL~fC$=!nfxhn>o$`qHY_+c#&E4pzA*Dk?7bb z?dZ`#-KlrH6V)}90aNRj{9d*j8m5zBb@fF<`~-)-*Ix_v1(X%Us=%!Bzshnomz9+1 z$5m!l30OtA^wU%(QiVN4)gGFnE4yxnwzsyGpvHr(U2`vAcXsa~oe=aK1Khc^*d6EH zA^h84pIH7}$c^hYBY)ql{qyRNTJ7I!<-5M>_aATFG~@dl<$YuE`StA|o@f_0YBy?c ztfza|3@O)2cnl}k)4X@$mFNUKGDVn`3%^8j7P^e940x^~Bg5|&NqQ2br zXjMF)t0^T2fA_R-S=uIL#;7S`w^~-*T$v t_K#T=D;j$Xtdgp>o$q%|+22kc8fH)WcH;eB-)rj|cYN=7`Lol+{{wRFJh=b> diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test index 9ffb27b621d78..acc44456d8f23 100644 --- a/mysql-test/main/statistics_json.test +++ b/mysql-test/main/statistics_json.test @@ -1,34 +1,56 @@ --source include/have_stat_tables.inc +--source include/have_sequence.inc +--source include/analyze-format.inc --echo # ---echo # Test that JSON is a valid histogram type and we can store JSON strings in mysql.column_stats +--echo # Test that we can store JSON arrays in histogram field mysql.column_stats when histogram_type=JSON --echo # --disable_warnings drop table if exists t1; --enable_warnings set @save_histogram_type=@@histogram_type; +set @save_histogram_size=@@histogram_size; CREATE TABLE t1 ( - a int NOT NULL PRIMARY KEY, - b varchar(32) -) ENGINE=MYISAM; + a int, + b varchar(32), + c char(2), + d double +); + +--disable_result_log +INSERT INTO t1 SELECT seq, seq, seq, seq from seq_1_to_25; +--enable_result_log SET histogram_type='JSON'; -SELECT @@histogram_type; +# set histogram size to be < row count (25 in this case) to see how histogram behaves +set histogram_size=10; + +ANALYZE TABLE t1 PERSISTENT FOR ALL; +SELECT * FROM mysql.column_stats WHERE table_name='t1'; +DELETE FROM mysql.column_stats; +DROP TABLE t1; + +create schema world; +use world; +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world_schema_utf8.inc +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log -INSERT INTO t1 VALUES - (7, 'xxxxxxxxxxxxxxxxxxxxxxxxxx'), - (17, 'vvvvvvvvvvvvv'); +set histogram_type='JSON'; +set histogram_size=25; +--disable_result_log +ANALYZE TABLE Country PERSISTENT FOR ALL; +--enable_result_log -ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); -DESCRIBE mysql.column_stats; -SELECT * FROM mysql.column_stats; +SELECT column_name, min_value, max_value, hist_size, hist_type, histogram FROM mysql.column_stats; set histogram_type=@save_histogram_type; +set histogram_size=@save_histogram_size; -## Remove against Milestone-2 -ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); -SELECT * FROM mysql.column_stats; -select table_name, hist_type, decode_histogram(hist_type, histogram ) from mysql.column_stats; - -DROP TABLE t1; \ No newline at end of file +DROP SCHEMA world; \ No newline at end of file diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index d2cad99f13022..cbbd7d30b4239 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1073,9 +1073,16 @@ class Column_stat: public Stat_table stat_field->store(stats->histogram.get_type() + 1); break; case COLUMN_STAT_HISTOGRAM: + if (stats->histogram.get_type() == JSON) + { + stat_field->store((char *) stats->histogram.get_values(), + strlen((char *) stats->histogram.get_values()), &my_charset_bin); + } else + { stat_field->store((char *) stats->histogram.get_values(), stats->histogram.get_size(), &my_charset_bin); - break; + } + break; } } } @@ -1588,7 +1595,7 @@ class Histogram_builder class Histogram_builder_json : public Histogram_builder { -std::vector bucket_bounds; +std::vector bucket_bounds; public: Histogram_builder_json(Field *col, uint col_len, ha_rows rows) @@ -1619,9 +1626,10 @@ std::vector bucket_bounds; return 0; if (count > bucket_capacity * (curr_bucket + 1)) { - auto *val= new StringBuffer; - column->val_str(val); - bucket_bounds.emplace_back(String(val->ptr(), val->length(), &my_charset_bin)); + column->store_field_value((uchar *) elem, col_length); + StringBuffer val; + column->val_str(&val); + bucket_bounds.emplace_back(val.ptr()); curr_bucket++; } return 0; @@ -1631,9 +1639,10 @@ std::vector bucket_bounds; Json_writer *writer = new Json_writer(); writer->start_array(); for(auto& value: bucket_bounds) { - writer->add_str(value); + writer->add_str(value.c_str()); } writer->end_array(); + histogram->set_size(bucket_bounds.size()); histogram->set_values((uchar *) writer->output.get_string()->ptr()); } }; diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 555d03cfa2232..a554721d50b13 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -153,9 +153,9 @@ class Histogram { switch (type) { case SINGLE_PREC_HB: + case JSON: return ((uint) (1 << 8) - 1); case DOUBLE_PREC_HB: - case JSON: return ((uint) (1 << 16) - 1); } return 1; @@ -166,9 +166,9 @@ class Histogram { switch (type) { case SINGLE_PREC_HB: + case JSON: return size; case DOUBLE_PREC_HB: - case JSON: return size / 2; } return 0; @@ -180,9 +180,9 @@ class Histogram DBUG_ASSERT(i < get_width()); switch (type) { case SINGLE_PREC_HB: + case JSON: return (uint) (((uint8 *) values)[i]); case DOUBLE_PREC_HB: - case JSON: return (uint) uint2korr(values + i * 2); } return 0; From 86d39f4e510435eaf9b047acaeabd498fb7c0ba1 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Fri, 2 Jul 2021 10:31:25 +0100 Subject: [PATCH 7/9] Fix garbage null values at end of json array elements Signed-off-by: Michael Okoko --- mysql-test/main/statistics_json.result | 363 ++++++++++++------------- sql/sql_statistics.cc | 2 +- 2 files changed, 182 insertions(+), 183 deletions(-) diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index a6b9458823ea0..7164198f2aeca 100644 --- a/mysql-test/main/statistics_json.result +++ b/mysql-test/main/statistics_json.result @@ -23,14 +23,14 @@ test t1 a 1 25 0.0000 4.0000 1.0000 10 JSON [ "3", "5", "7", - "10x~��", - "12�~��", - "14P�罣", - "16x��", - "198���", - "218���", - "23����" -]������������������������ + "10", + "12", + "14", + "16", + "19", + "21", + "23" +]������������������������������������������������������������������ test t1 b 1 9 0.0000 1.6400 1.0000 10 JSON [ "11", "13", @@ -48,13 +48,13 @@ test t1 c 1 9 0.0000 2.0000 1.0000 10 JSON [ "13", "15", "18", - "2 ", + "2", "21", "23", - "3 ", - "5 ", - "7 " -]��������������������������������������������������������������� + "3", + "5", + "7" +]������������������������������������������������������������������� test t1 d 1 25 0.0000 8.0000 1.0000 10 JSON [ "3", "5", @@ -77,32 +77,59 @@ ANALYZE TABLE Country PERSISTENT FOR ALL; SELECT column_name, min_value, max_value, hist_size, hist_type, histogram FROM mysql.column_stats; column_name min_value max_value hist_size hist_type histogram Code ABW ZWE 25 JSON [ - "ARM United States Minor Outlying Islands ", - "BEL United States Minor Outlying Islands ", - "BLZ United States Minor Outlying Islands ", - "CAF United States Minor Outlying Islands ", - "COG United States Minor Outlying Islands ", - "CZE United States Minor Outlying Islands ", - "ERI United States Minor Outlying Islands ", - "FRO United States Minor Outlying Islands ", - "GMB United States Minor Outlying Islands ", - "GUY United States Minor Outlying Islands ", - "IRL United States Minor Outlying Islands ", - "KAZ United States Minor Outlying Islands ", - "LBN United States Minor Outlying Islands ", - "LVA United States Minor Outlying Islands ", - "MKD United States Minor Outlying Islands ", - "MUS United States Minor Outlying Islands ", - "NIC United States Minor Outlying Islands ", - "PAN United States Minor Outlying Islands ", - "PRT United States Minor Outlying Islands ", - "SAU United States Minor Outlying Islands ", - "SMR United States Minor Outlying Islands ", - "SYC United States Minor Outlying Islands ", - "TMP United States Minor Outlying Islands ", - "UKR United States Minor Outlying Islands ", - "VIR United States Minor Outlying Islands " -]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Q( + "ARM", + "BEL", + "BLZ", + "CAF", + "COG", + "CZE", + "ERI", + "FRO", + "GMB", + "GUY", + "IRL", + "KAZ", + "LBN", + "LVA", + "MKD", + "MUS", + "NIC", + "PAN", + "PRT", + "SAU", + "SMR", + "SYC", + "TMP", + "UKR", + "VIR" +]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 +Name Afghanistan Zimbabwe 25 JSON [ + "Argentina", + "Barbados", + "Botswana", + "Cameroon", + "Cocos (Keeling) Islands", + "Czech Republic", + "El Salvador", + "France", + "Gibraltar", + "Guyana", + "Iran", + "Kenya", + "Libyan Arab Jamahiriya", + "Maldives", + "Micronesia, Federated States of", + "Nepal", + "Norfolk Island", + "Papua New Guinea", + "Romania", + "Samoa", + "Solomon Islands", + "Svalbard and Jan Mayen", + "Togo", + "Uganda", + "Venezuela" +]�����������������������������������������������������������������������������������������������������a SurfaceArea 0.40 17075400.00 25 JSON [ "36.00", "151.00", @@ -129,25 +156,25 @@ SurfaceArea 0.40 17075400.00 25 JSON [ "1104300.00", "1648195.00", "2724900.00" -] +]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Population 0 1277558000 25 JSON [ - "1000"��", - "8000�O[U", - "25000��", - "65000��", - "94000��", - "181000�", - "293000�", - "453000�", - "817000�", - "1439200", - "2542000", - "3337000", - "3869000", - "4807000", - "5496000", - "7430000", - "8861400", + "1000", + "8000", + "25000", + "65000", + "94000", + "181000", + "293000", + "453000", + "817000", + "1439200", + "2542000", + "3337000", + "3869000", + "4807000", + "5496000", + "7430000", + "8861400", "10278100", "11669000", "16125000", @@ -156,71 +183,106 @@ Population 0 1277558000 25 JSON [ "40377000", "61399000", "111506000" -] +]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Capital 1 4074 25 JSON [ - "62h�#��", - "149�#��", - "201�#��", - "553�#��", - "645�#��", - "902�#��", - "922�#��", - "1109#��", - "1530#��", - "1859#��", - "2296#��", - "2430#��", - "2452#��", - "2482#��", - "2689#��", - "2729#��", - "2831#��", - "2919#��", - "3047#��", - "3162#��", - "3209#��", - "3250#��", - "3336#��", - "3426#��", - "3538#��" -] ", - "Cameroon � + "62", + "149", + "201", + "553", + "645", + "902", + "922", + "1109", + "1530", + "1859", + "2296", + "2430", + "2452", + "2482", + "2689", + "2729", + "2831", + "2919", + "3047", + "3162", + "3209", + "3250", + "3336", + "3426", + "3538" +]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� ID 1 4079 10 JSON [ - "371r!��", - "742�!��", - "1113!��", - "1484!��", - "1855"��", - "2225*��", - "2596*��", - "2967*��", - "3338*��", - "3709+��" -]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� + "371", + "742", + "1113", + "1484", + "1855", + "2225", + "2596", + "2967", + "3338", + "3709" +]��������������������������������������������� +Name A Coruña (La Coruña) Ã…rhus 10 JSON [ + "Berdytšiv", + "Clermont-Ferrand", + "Gatineau", + "Itapecerica da Serra", + "Kuytun", + "Milano", + "Ota", + "Roanoke", + "Split", + "Ulsan" +]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Country ABW ZWE 10 JSON [ - "BRA tg", - "CHN tg", - "DZA tg", - "IDN tg", - "IND tg", - "JPN tg", - "MEX tg", - "PHL tg", - "RUS tg", - "USA tg" -] PSE tg + "BRA", + "CHN", + "DZA", + "IDN", + "IND", + "JPN", + "MEX", + "PHL", + "RUS", + "USA" +]����������������������������������������������������� Population 42 10500000 10 JSON [ - "96002��", - "105819�", - "118326�", - "132318�", - "152397�", - "181900�", - "221400�", - "288173�", - "398300�", - "670208�" -]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������! + "96002", + "105819", + "118326", + "132318", + "152397", + "181900", + "221400", + "288173", + "398300", + "670208" +]������������������������ +Country ABW ZWE 10 JSON [ + "BGD", + "CMR", + "ESP", + "GUF", + "KAZ", + "MDA", + "NAM", + "PNG", + "SVK", + "UGA" +]����������������������������������������������������� +Language Abhyasi [South]Mande 10 JSON [ + "Bariba", + "Creole English", + "English", + "Georgiana", + "Italian", + "Lomwe", + "Moravian", + "Punjabi", + "Soga", + "Tigrinja" +] Percentage 0.0 99.9 10 JSON [ "0.2", "0.6", @@ -232,70 +294,7 @@ Percentage 0.0 99.9 10 JSON [ "17.7", "45.5", "87.5" -]�������������������������������������������������1 -Name Afghanistan Zimbabwe 25 JSON [ - "Argentina ", - "Barbados ", - "Botswana ", - "Cameroon ", - "Cocos (Keeling) Islands ", - "Czech Republic ", - "El Salvador ", - "France ", - "Gibraltar ", - "Guyana ", - "Iran ", - "Kenya ", - "Libyan Arab Jamahiriya ", - "Maldives ", - "Micronesia, Federated States of ", - "Nepal ", - "Norfolk Island ", - "Papua New Guinea ", - "Romania ", - "Samoa ", - "Solomon Islands ", - "Svalbard and Jan Mayen ", - "Togo ", - "Uganda ", - "Venezuela " -]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������! -Name A Coruña (La Coruña) Ã…rhus 10 JSON [ - "Berdytšiv PSE tg", - "Clermont-Ferrand PSE tg", - "Gatineau PSE tg", - "Itapecerica da Serra PSE tg", - "Kuytun PSE tg", - "Milano PSE tg", - "Ota PSE tg", - "Roanoke PSE tg", - "Split PSE tg", - "Ulsan PSE tg" -]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������A -Country ABW ZWE 10 JSON [ - "BGD Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "CMR Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "ESP Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "GUF Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "KAZ Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "MDA Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "NAM Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "PNG Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "SVK Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������", - "UGA Portuguese ��L>����������������������������������������������������������������������������������������������������������������������������" -]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� -Language Abhyasi [South]Mande 10 JSON [ - "Bariba ��L>����������������������������������������������������������������������������������������������������������������������������", - "Creole English ��L>����������������������������������������������������������������������������������������������������������������������������", - "English ��L>����������������������������������������������������������������������������������������������������������������������������", - "Georgiana ��L>����������������������������������������������������������������������������������������������������������������������������", - "Italian ��L>����������������������������������������������������������������������������������������������������������������������������", - "Lomwe ��L>����������������������������������������������������������������������������������������������������������������������������", - "Moravian ��L>����������������������������������������������������������������������������������������������������������������������������", - "Punjabi ��L>����������������������������������������������������������������������������������������������������������������������������", - "Soga ��L>����������������������������������������������������������������������������������������������������������������������������", - "Tigrinja ��L>����������������������������������������������������������������������������������������������������������������������������" -]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +]�������������������������������������������������q set histogram_type=@save_histogram_type; set histogram_size=@save_histogram_size; DROP SCHEMA world; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index cbbd7d30b4239..15736778cc047 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1629,7 +1629,7 @@ std::vector bucket_bounds; column->store_field_value((uchar *) elem, col_length); StringBuffer val; column->val_str(&val); - bucket_bounds.emplace_back(val.ptr()); + bucket_bounds.emplace_back(val.c_ptr()); curr_bucket++; } return 0; From d2ff2506bd5ff7bb7a459979493997a57b51f7da Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Fri, 2 Jul 2021 10:50:51 +0100 Subject: [PATCH 8/9] Fix garbage null values at end of histogram json Signed-off-by: Michael Okoko --- mysql-test/main/statistics_json.result | 30 +++++++++++++------------- sql/sql_statistics.cc | 3 ++- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 7164198f2aeca..e53a6f72f12b5 100644 --- a/mysql-test/main/statistics_json.result +++ b/mysql-test/main/statistics_json.result @@ -30,7 +30,7 @@ test t1 a 1 25 0.0000 4.0000 1.0000 10 JSON [ "19", "21", "23" -]������������������������������������������������������������������ +] test t1 b 1 9 0.0000 1.6400 1.0000 10 JSON [ "11", "13", @@ -42,7 +42,7 @@ test t1 b 1 9 0.0000 1.6400 1.0000 10 JSON [ "3", "5", "7" -]������������������������������������������������������������������� +] test t1 c 1 9 0.0000 2.0000 1.0000 10 JSON [ "11", "13", @@ -54,7 +54,7 @@ test t1 c 1 9 0.0000 2.0000 1.0000 10 JSON [ "3", "5", "7" -]������������������������������������������������������������������� +] test t1 d 1 25 0.0000 8.0000 1.0000 10 JSON [ "3", "5", @@ -66,7 +66,7 @@ test t1 d 1 25 0.0000 8.0000 1.0000 10 JSON [ "19", "21", "23" -]�����������������������������������������������������������������e +] DELETE FROM mysql.column_stats; DROP TABLE t1; create schema world; @@ -102,7 +102,7 @@ Code ABW ZWE 25 JSON [ "TMP", "UKR", "VIR" -]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������0 +] Name Afghanistan Zimbabwe 25 JSON [ "Argentina", "Barbados", @@ -129,7 +129,7 @@ Name Afghanistan Zimbabwe 25 JSON [ "Togo", "Uganda", "Venezuela" -]�����������������������������������������������������������������������������������������������������a +] SurfaceArea 0.40 17075400.00 25 JSON [ "36.00", "151.00", @@ -156,7 +156,7 @@ SurfaceArea 0.40 17075400.00 25 JSON [ "1104300.00", "1648195.00", "2724900.00" -]�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +] Population 0 1277558000 25 JSON [ "1000", "8000", @@ -183,7 +183,7 @@ Population 0 1277558000 25 JSON [ "40377000", "61399000", "111506000" -]����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +] Capital 1 4074 25 JSON [ "62", "149", @@ -210,7 +210,7 @@ Capital 1 4074 25 JSON [ "3336", "3426", "3538" -]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +] ID 1 4079 10 JSON [ "371", "742", @@ -222,7 +222,7 @@ ID 1 4079 10 JSON [ "2967", "3338", "3709" -]��������������������������������������������� +] Name A Coruña (La Coruña) Ã…rhus 10 JSON [ "Berdytšiv", "Clermont-Ferrand", @@ -234,7 +234,7 @@ Name A Coruña (La Coruña) Ã…rhus 10 JSON [ "Roanoke", "Split", "Ulsan" -]������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� +] Country ABW ZWE 10 JSON [ "BRA", "CHN", @@ -246,7 +246,7 @@ Country ABW ZWE 10 JSON [ "PHL", "RUS", "USA" -]����������������������������������������������������� +] Population 42 10500000 10 JSON [ "96002", "105819", @@ -258,7 +258,7 @@ Population 42 10500000 10 JSON [ "288173", "398300", "670208" -]������������������������ +] Country ABW ZWE 10 JSON [ "BGD", "CMR", @@ -270,7 +270,7 @@ Country ABW ZWE 10 JSON [ "PNG", "SVK", "UGA" -]����������������������������������������������������� +] Language Abhyasi [South]Mande 10 JSON [ "Bariba", "Creole English", @@ -294,7 +294,7 @@ Percentage 0.0 99.9 10 JSON [ "17.7", "45.5", "87.5" -]�������������������������������������������������q +] set histogram_type=@save_histogram_type; set histogram_size=@save_histogram_size; DROP SCHEMA world; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 15736778cc047..85ee5a9060989 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1643,7 +1643,8 @@ std::vector bucket_bounds; } writer->end_array(); histogram->set_size(bucket_bounds.size()); - histogram->set_values((uchar *) writer->output.get_string()->ptr()); + Binary_string *json_string = (Binary_string *) writer->output.get_string(); + histogram->set_values((uchar *) json_string->c_ptr()); } }; From 5ddb8069145b518426be7fd31881d1d3fa5f53b4 Mon Sep 17 00:00:00 2001 From: Michael Okoko Date: Wed, 7 Jul 2021 22:45:43 +0100 Subject: [PATCH 9/9] Properly initialize bucket bounds vector Signed-off-by: Michael Okoko --- sql/sql_statistics.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 85ee5a9060989..56e20ecf48e08 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -35,6 +35,7 @@ #include "my_json_writer.h" #include +#include /* The system variable 'use_stat_tables' can take one of the @@ -1595,7 +1596,7 @@ class Histogram_builder class Histogram_builder_json : public Histogram_builder { -std::vector bucket_bounds; +std::vector bucket_bounds = {}; public: Histogram_builder_json(Field *col, uint col_len, ha_rows rows) @@ -1611,7 +1612,6 @@ std::vector bucket_bounds; count= 0; count_distinct= 0; count_distinct_single_occurence= 0; - bucket_bounds = {}; } ~Histogram_builder_json() override = default;