diff --git a/mysql-test/main/statistics_json.result b/mysql-test/main/statistics_json.result index 3e7a9a43634..a6b9458823e 100644 Binary files a/mysql-test/main/statistics_json.result and b/mysql-test/main/statistics_json.result differ diff --git a/mysql-test/main/statistics_json.test b/mysql-test/main/statistics_json.test index 9ffb27b621d..acc44456d8f 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; -INSERT INTO t1 VALUES - (7, 'xxxxxxxxxxxxxxxxxxxxxxxxxx'), - (17, 'vvvvvvvvvvvvv'); +ANALYZE TABLE t1 PERSISTENT FOR ALL; +SELECT * FROM mysql.column_stats WHERE table_name='t1'; +DELETE FROM mysql.column_stats; +DROP TABLE t1; -ANALYZE TABLE t1 PERSISTENT FOR COLUMNS(b) INDEXES(); -DESCRIBE mysql.column_stats; -SELECT * FROM mysql.column_stats; +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 + +set histogram_type='JSON'; +set histogram_size=25; +--disable_result_log +ANALYZE TABLE Country PERSISTENT FOR ALL; +--enable_result_log + +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 d2cad99f130..cbbd7d30b42 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -1073,9 +1073,16 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: 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 555d03cfa22..a554721d50b 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -153,9 +153,9 @@ private: { 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 @@ public: { 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 @@ private: 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;