commit ea8b77c435bccd88c3082030159556dd3a78404c
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date:   Sun Aug 14 19:19:54 2022 +0200

    Implementation of BERNOULLI for TABLESAMPLE

diff --git a/mysql-test/main/sample_select.result b/mysql-test/main/sample_select.result
new file mode 100644
index 00000000000..3e32a8f2113
--- /dev/null
+++ b/mysql-test/main/sample_select.result
@@ -0,0 +1,14 @@
+create table t1 (id int not null primary key,
+val int);
+select avg(id),count(id) from t1;
+avg(id)	count(id)
+500.5000	1000
+# use second table, because count() do not work correctly
+# with TABLESAMPLE
+create table t2 (id int not null,
+val int);
+insert into t2 select * from t1 TABLESAMPLE BERNOULLI (50);
+select abs(avg(id) - 500.5) < 500.5*0.1, abs(count(id) - 500) < 500*0.1 from t2;
+abs(avg(id) - 500.5) < 500.5*0.1	abs(count(id) - 500) < 500*0.1
+1	1
+drop table t1, t2;
diff --git a/mysql-test/main/sample_select.test b/mysql-test/main/sample_select.test
new file mode 100644
index 00000000000..0b050ad6d3d
--- /dev/null
+++ b/mysql-test/main/sample_select.test
@@ -0,0 +1,25 @@
+create table t1 (id int not null primary key,
+                 val int);
+
+let $1=1000;
+
+--disable_query_log
+while ($1)
+{
+  eval insert into t1 values ( $1 , 10);
+  dec $1;
+}
+--enable_query_log
+
+select avg(id),count(id) from t1;
+
+--echo # use second table, because count() do not work correctly
+--echo # with TABLESAMPLE
+create table t2 (id int not null,
+                 val int);
+ 
+insert into t2 select * from t1 TABLESAMPLE BERNOULLI (50);
+
+select abs(avg(id) - 500.5) < 500.5*0.1, abs(count(id) - 500) < 500*0.1 from t2;
+
+drop table t1, t2;
diff --git a/mysql-test/suite/perfschema/r/digest_view.result b/mysql-test/suite/perfschema/r/digest_view.result
index 3fd7a090459..4c4fed39430 100644
--- a/mysql-test/suite/perfschema/r/digest_view.result
+++ b/mysql-test/suite/perfschema/r/digest_view.result
@@ -191,17 +191,17 @@ SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR
 FROM performance_schema.events_statements_summary_by_digest
 ORDER BY DIGEST_TEXT;
 SCHEMA_NAME	DIGEST	DIGEST_TEXT	COUNT_STAR
-test	333a53e537d74bf74dd28c78ad5b23dd	EXPLAIN SELECT * FROM `test` . `v1` 	1
-test	1fb578da66e6583bae8e64061486f1b1	EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 	1
-test	923bca939a55826e231e1335016ba418	EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 	1
-test	6fa6d75432fd499d1c7d6f964c8310a2	EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 	1
-test	3421da1ec8ecb8cac97e12a0609f73cb	EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 	1
-test	c2f68fd41bfbf3acd52eb5e7306b0c00	SELECT * FROM `test` . `v1` 	1
-test	dd68812cbe4c1ed5a38921222981f8c5	SELECT * FROM `test` . `v1` WHERE `a` = ? 	1
-test	7563bcc32c6d0d872c8d9f0bf7717e6a	SELECT * FROM `test` . `v1` WHERE `b` > ? 	1
-test	0817c53833dc6adbca581e8fe4c598c7	SELECT `a` , `b` FROM `test` . `v1` 	1
-test	a5f13903c70812ae08fa8c084e9cd503	SELECT `b` , `a` FROM `test` . `v1` 	1
-test	66b14a14f2a42e1335dd28dfad8ea084	TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 	1
+test	0cd509bef4fcaec486c6fe40f5d0605d	EXPLAIN SELECT * FROM `test` . `v1` 	1
+test	78984efc9d252b92f78c0301adfb885f	EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 	1
+test	5a70d7b33fff3b10abe27f89e86153e2	EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 	1
+test	0e7ac33d57dba3db9619605f3e5beab8	EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 	1
+test	94e84b1d8e23bb5072e90b93e819f90e	EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 	1
+test	4bee0754c6f0dd9b07c7924d8a16a316	SELECT * FROM `test` . `v1` 	1
+test	d17fa9790594cd1f8df5314c95f7f7bf	SELECT * FROM `test` . `v1` WHERE `a` = ? 	1
+test	dd83248bed00a08e37ec370f4219d938	SELECT * FROM `test` . `v1` WHERE `b` > ? 	1
+test	72144fe1e02106cfdf84ca3817f60f03	SELECT `a` , `b` FROM `test` . `v1` 	1
+test	b605d56234b6b28974e8ec9562a544a2	SELECT `b` , `a` FROM `test` . `v1` 	1
+test	6a416f83fde8bae670e01cd1b29b1c18	TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 	1
 DROP TABLE test.v1;
 CREATE VIEW test.v1 AS SELECT * FROM test.t1;
 EXPLAIN SELECT * from test.v1;
@@ -248,19 +248,19 @@ SELECT SCHEMA_NAME, DIGEST, DIGEST_TEXT, COUNT_STAR
 FROM performance_schema.events_statements_summary_by_digest
 ORDER BY DIGEST_TEXT;
 SCHEMA_NAME	DIGEST	DIGEST_TEXT	COUNT_STAR
-test	98531b331031b84ddfbb2de8b601a704	CREATE VIEW `test` . `v1` AS SELECT * FROM `test` . `t1` 	1
-test	5352d7d117e97fecd312e354e9e290ce	DROP TABLE `test` . `v1` 	1
-test	333a53e537d74bf74dd28c78ad5b23dd	EXPLAIN SELECT * FROM `test` . `v1` 	2
-test	1fb578da66e6583bae8e64061486f1b1	EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 	2
-test	923bca939a55826e231e1335016ba418	EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 	2
-test	6fa6d75432fd499d1c7d6f964c8310a2	EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 	2
-test	3421da1ec8ecb8cac97e12a0609f73cb	EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 	2
-test	c2f68fd41bfbf3acd52eb5e7306b0c00	SELECT * FROM `test` . `v1` 	2
-test	dd68812cbe4c1ed5a38921222981f8c5	SELECT * FROM `test` . `v1` WHERE `a` = ? 	2
-test	7563bcc32c6d0d872c8d9f0bf7717e6a	SELECT * FROM `test` . `v1` WHERE `b` > ? 	2
-test	21c19dd7ef5b894f3e32d0585cb3007f	SELECT SCHEMA_NAME , `DIGEST` , `DIGEST_TEXT` , `COUNT_STAR` FROM `performance_schema` . `events_statements_summary_by_digest` ORDER BY `DIGEST_TEXT` 	1
-test	0817c53833dc6adbca581e8fe4c598c7	SELECT `a` , `b` FROM `test` . `v1` 	2
-test	a5f13903c70812ae08fa8c084e9cd503	SELECT `b` , `a` FROM `test` . `v1` 	2
-test	66b14a14f2a42e1335dd28dfad8ea084	TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 	1
+test	81ba956e271ccc6710100f66fbe89a95	CREATE VIEW `test` . `v1` AS SELECT * FROM `test` . `t1` 	1
+test	741e23323033aa1a27d484e31273d1f7	DROP TABLE `test` . `v1` 	1
+test	0cd509bef4fcaec486c6fe40f5d0605d	EXPLAIN SELECT * FROM `test` . `v1` 	2
+test	78984efc9d252b92f78c0301adfb885f	EXPLAIN SELECT * FROM `test` . `v1` WHERE `a` = ? 	2
+test	5a70d7b33fff3b10abe27f89e86153e2	EXPLAIN SELECT * FROM `test` . `v1` WHERE `b` > ? 	2
+test	0e7ac33d57dba3db9619605f3e5beab8	EXPLAIN SELECT `a` , `b` FROM `test` . `v1` 	2
+test	94e84b1d8e23bb5072e90b93e819f90e	EXPLAIN SELECT `b` , `a` FROM `test` . `v1` 	2
+test	4bee0754c6f0dd9b07c7924d8a16a316	SELECT * FROM `test` . `v1` 	2
+test	d17fa9790594cd1f8df5314c95f7f7bf	SELECT * FROM `test` . `v1` WHERE `a` = ? 	2
+test	dd83248bed00a08e37ec370f4219d938	SELECT * FROM `test` . `v1` WHERE `b` > ? 	2
+test	37b6bbf54848f2a0bfff4c3cf142d50a	SELECT SCHEMA_NAME , `DIGEST` , `DIGEST_TEXT` , `COUNT_STAR` FROM `performance_schema` . `events_statements_summary_by_digest` ORDER BY `DIGEST_TEXT` 	1
+test	72144fe1e02106cfdf84ca3817f60f03	SELECT `a` , `b` FROM `test` . `v1` 	2
+test	b605d56234b6b28974e8ec9562a544a2	SELECT `b` , `a` FROM `test` . `v1` 	2
+test	6a416f83fde8bae670e01cd1b29b1c18	TRUNCATE TABLE `performance_schema` . `events_statements_summary_by_digest` 	1
 DROP VIEW test.v1;
 DROP TABLE test.t1;
diff --git a/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result b/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result
index ff554155f33..4bbe49f4be3 100644
--- a/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result
+++ b/mysql-test/suite/perfschema/r/start_server_low_digest_sql_length.result
@@ -8,5 +8,5 @@ SELECT 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1
 ####################################
 SELECT event_name, digest, digest_text, sql_text FROM events_statements_history_long;
 event_name	digest	digest_text	sql_text
-statement/sql/select	96a6bb95edaf100857f09c968aca354b	SELECT ? + ? + 	SELECT ...
-statement/sql/truncate	c1d647bb870f2c63c22a16707bb8aee3	TRUNCATE TABLE 	truncat...
+statement/sql/select	157d58c66754c972235fd9535db86f79	SELECT ? + ? + 	SELECT ...
+statement/sql/truncate	a8b0b5b2e2ff71e80a50828553a70e9a	TRUNCATE TABLE 	truncat...
diff --git a/sql/lex.h b/sql/lex.h
index ae70537c73b..a81f2b50bb0 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -87,6 +87,7 @@ SYMBOL symbols[] = {
   { "BACKUP",	        SYM(BACKUP_SYM)},
   { "BEFORE",	        SYM(BEFORE_SYM)},
   { "BEGIN",	        SYM(BEGIN_MARIADB_SYM)},
+  { "BERNOULLI",        SYM(BERNOULLI_SYM)},
   { "BETWEEN",		SYM(BETWEEN_SYM)},
   { "BIGINT",		SYM(BIGINT)},
   { "BINARY",		SYM(BINARY)},
diff --git a/sql/records.cc b/sql/records.cc
index 9eadf788585..e4cae4696c4 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -34,6 +34,7 @@
 #include "sql_class.h"                          // THD
 #include "sql_base.h"
 #include "sql_sort.h"                           // SORT_ADDON_FIELD
+#include "sql_statistics.h"
 
 static int rr_quick(READ_RECORD *info);
 int rr_sequential(READ_RECORD *info);
@@ -324,10 +325,9 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
   }
   else if (table->tablesample)
   {
-    double fract= table->tablesample->val_real() / 100.0;
-    info->sample_counter= (ha_rows)(table->file->records() * fract + 0.5);
+    info->tablesample= table->tablesample;
     info->read_record_func= rr_sequential_sample;
-    if (table->file->ha_sample_init())
+    if (table->tablesample->init(thd, table))
       DBUG_RETURN(1);
   }
   else
@@ -535,17 +535,10 @@ int rr_sequential(READ_RECORD *info)
 
 int rr_sequential_sample(READ_RECORD *info)
 {
-  int tmp;
-  if (!info->sample_counter)
-    return -1; // End of file
-
-  info->sample_counter--;
-  while ((tmp= info->table->file->ha_sample_next(info->record())))
-  {
-    tmp= rr_handle_error(info, tmp);
-    break;
-  }
-  return tmp;
+  int rc= info->tablesample->next(info->record());
+  if (rc)
+    rc= rr_handle_error(info, rc);
+  return rc;
 }
 
 
diff --git a/sql/records.h b/sql/records.h
index 579e0e2bf3a..9bbfbbea1a8 100644
--- a/sql/records.h
+++ b/sql/records.h
@@ -61,7 +61,7 @@ struct READ_RECORD
   SQL_SELECT *select;
   uint ref_length, reclength, rec_cache_size, error_offset;
 
-  ha_rows sample_counter;
+  Statistic_collector *tablesample;
   /**
     Counting records when reading result from filesort().
     Used when filesort leaves the result in the filesort buffer.
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index f2a38e27722..ccee3c8cb08 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2672,6 +2672,70 @@ int collect_statistics_for_index(THD *thd, TABLE *table, uint index)
 }
 
 
+bool System_staticitc_collector::init(THD *thd __attribute__((unused)),
+                                      TABLE *table)
+{
+  file= table->file;
+  limit= (ha_rows)(file->records() * sample_fraction + 0.5);
+  if (file->ha_sample_init())
+    return (TRUE);
+  return (FALSE);
+}
+
+int System_staticitc_collector::next(uchar *record)
+{
+  int rc= 0;
+  if (!limit)
+    return HA_ERR_END_OF_FILE;
+
+  if (!(rc= file->ha_sample_next(record)))
+    limit --;
+  return rc;
+}
+
+void System_staticitc_collector::close()
+{
+  if (file)
+  {
+    file->ha_sample_end();
+    file= 0;
+  }
+}
+
+bool Bernoulli_staticitc_collector::init(THD *thd, TABLE *table)
+{
+  this->thd= thd;
+  this->file= table->file;
+  this->sample_fraction= sample_fraction;
+  if (file->ha_rnd_init(TRUE))
+    return (TRUE);
+  return (FALSE);
+}
+
+int Bernoulli_staticitc_collector::next(uchar *record)
+{
+  int rc;
+  while (!(rc= file->ha_rnd_next(record)))
+  {
+    if (thd->killed)
+      return 0;
+
+    if (thd_rnd(thd) <= sample_fraction)
+      return 0;
+  }
+  return rc;
+}
+
+void Bernoulli_staticitc_collector::close()
+{
+  if (file)
+  {
+    file->ha_rnd_end();
+    file= 0;
+  }
+}
+
+
 /**
   @brief 
   Collect statistical data for a table
@@ -2763,73 +2827,42 @@ int collect_statistics_for_table(THD *thd, TABLE *table)
 
   restore_record(table, s->default_values);
 
-  if(file->ha_table_flags() & HA_NATIVE_SAMPLING)
-  {
-    if(!(rc= file->ha_sample_init())) {
-      DEBUG_SYNC(table->in_use, "statistics_collection_start");
-      rows = file->records() * (thd->variables.sample_percentage / 100);
-
-      for (ulonglong i= 0; i < rows; ++i)
-      {
-        rc = file->ha_sample_next(table->record[0]);
-        if (thd->killed)
-          break;
-
-        if (rc)
-          break;
-        for (field_ptr= table->field; *field_ptr; field_ptr++)
-        {
-          table_field= *field_ptr;
-          if (!table_field->collected_stats)
-            continue;
-          if ((rc= table_field->collected_stats->add()))
-            break;
-        }
-        if (rc)
-          break;
-      }
-      file->ha_sample_end();
-    }
-    rc= (rc == 0 && !thd->killed) ? 0 : 1;
-  }
+  Statistic_collector *collector;
+  if (file->ha_table_flags() & HA_NATIVE_SAMPLING)
+    collector=
+      new (thd->mem_root) System_staticitc_collector(sample_fraction);
   else
-  {
+    collector=
+      new (thd->mem_root) Bernoulli_staticitc_collector(sample_fraction);
 
-    /* Perform a full table scan to collect statistics on 'table's columns */
-    if (!(rc= file->ha_rnd_init(TRUE)))
-    {
-      DEBUG_SYNC(table->in_use, "statistics_collection_start");
+  if (collector->init(thd, table))
+    DBUG_RETURN(1);
+  DEBUG_SYNC(table->in_use, "statistics_collection_start");
 
-      while ((rc= file->ha_rnd_next(table->record[0])) != HA_ERR_END_OF_FILE)
-      {
-        if (thd->killed)
-          break;
+  while ((rc= collector->next(table->record[0])) != HA_ERR_END_OF_FILE)
+  {
+    if (thd->killed)
+      break;
 
-        if (rc)
-          break;
+    if (rc)
+      break;
 
-        if (thd_rnd(thd) <= sample_fraction)
-        {
-          for (field_ptr= table->field; *field_ptr; field_ptr++)
-          {
-            table_field= *field_ptr;
-            if (!table_field->collected_stats)
-              continue;
-            if ((rc= table_field->collected_stats->add()))
-              break;
-          }
-          if (rc)
-            break;
-          rows++;
-        }
-      }
-      file->ha_rnd_end();
+    for (field_ptr= table->field; *field_ptr; field_ptr++)
+    {
+      table_field= *field_ptr;
+      if (!table_field->collected_stats)
+        continue;
+      if ((rc= table_field->collected_stats->add()))
+        break;
     }
-    rc= (rc == HA_ERR_END_OF_FILE && !thd->killed) ? 0 : 1;
+    if (rc)
+      break;
+    rows++;
   }
+  collector->close();
+  rc= (rc == HA_ERR_END_OF_FILE && !thd->killed) ? 0 : 1;
 
-
-  /* 
+  /*
     Calculate values for all statistical characteristics on columns and
     and for each field f of 'table' save them in the write_stat structure
     from the Field object for f. 
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index c0df15ea4ad..7a938304eca 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -620,4 +620,48 @@ class Index_statistics
 
 };
 
+class Statistic_collector: public Sql_alloc
+{
+  protected:
+  handler *file;
+  double sample_fraction;
+
+  public:
+  Statistic_collector(double fraction):
+    file(0),
+    sample_fraction(fraction)
+  {}
+  virtual ~Statistic_collector()
+  {}
+
+
+  virtual bool init(THD *thd, TABLE *table)= 0;
+  virtual int next(uchar *record)= 0;
+  virtual void close()= 0;
+};
+
+class System_staticitc_collector: public Statistic_collector
+{
+  ha_rows limit;
+  public:
+  System_staticitc_collector(double fraction):
+    Statistic_collector(fraction)
+  {}
+  bool init(THD *thd, TABLE *table) override;
+  int next(uchar *record) override;
+  void close() override;
+};
+
+class Bernoulli_staticitc_collector: public Statistic_collector
+{
+  THD *thd;
+  public:
+  Bernoulli_staticitc_collector(double fraction):
+    Statistic_collector(fraction)
+  {}
+  bool init(THD *thd, TABLE *table) override;
+  int next(uchar *record) override;
+  void close() override;
+};
+
 #endif /* SQL_STATISTICS_H */
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 2ad1a02170e..2b1e940de0c 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -69,6 +69,7 @@
 #include "my_base.h"
 #include "sql_type_json.h"
 #include "json_table.h"
+#include "sql_statistics.h"
 
 /* this is to get the bison compilation windows warnings out */
 #ifdef _MSC_VER
@@ -329,6 +330,7 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
   enum Column_definition::enum_column_versioning vers_column_versioning;
   enum plsql_cursor_attr_t plsql_cursor_attr;
   privilege_t privilege;
+  Statistic_collector *sample_collector;
 }
 
 %{
@@ -755,6 +757,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
 %token  <kwd>  BACKUP_SYM
 %token  <kwd>  BEGIN_MARIADB_SYM             /* SQL-2003-R, PLSQL-R */
 %token  <kwd>  BEGIN_ORACLE_SYM              /* SQL-2003-R, PLSQL-R */
+%token  <kwd>  BERNOULLI_SYM
 %token  <kwd>  BINLOG_SYM
 %token  <kwd>  BIT_SYM                       /* MYSQL-FUNC */
 %token  <kwd>  BLOCK_SYM
@@ -1461,7 +1464,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
         ws_level_flag_desc ws_level_flag_reverse ws_level_flags
         opt_ws_levels ws_level_list ws_level_list_item ws_level_number
         ws_level_range ws_level_list_or_range bool
-        field_options last_field_options
+        field_options last_field_options system_or_bernoully
 
 %type <ulonglong_number>
         ulonglong_num real_ulonglong_num
@@ -1511,7 +1514,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
 %type <item_param> param_marker
 
 %type <item_num>
-        NUM_literal opt_table_sample
+        NUM_literal
+
+%type <sample_collector>
+        opt_table_sample
 
 %type <item_basic_constant> text_literal
 
@@ -11754,13 +11760,26 @@ join_table_parens:
           }
         ;
 
+system_or_bernoully:
+          SYSTEM    { $$= 1; }
+        | BERNOULLI_SYM { $$= 0; }
+        ;
+
 /* psergey */
 opt_table_sample:
-          /* empty */ { $$=0; }
-        | TABLESAMPLE SYSTEM '(' NUM_literal ')'
-        {
-          $$=$4;
-        }
+          /* empty */
+          {
+            $$= 0;
+          }
+        | TABLESAMPLE system_or_bernoully '(' NUM_literal ')'
+          {
+            if ($2)
+              $$= new (thd->mem_root)
+                System_staticitc_collector($4->val_real()/100.0);
+            else
+              $$= new (thd->mem_root)
+                Bernoulli_staticitc_collector($4->val_real()/100.0);
+          }
         ;
 
 table_primary_ident:
@@ -11778,7 +11797,9 @@ table_primary_ident:
             if ($3)
               $$->vers_conditions= Lex->vers_conditions;
             if ($6)
+            {
               $$->tablesample= $6;
+            }
           }
         ;
 
@@ -15728,6 +15749,7 @@ keyword_sp_var_and_label:
         | AUTO_SYM
         | AVG_ROW_LENGTH
         | AVG_SYM
+        | BERNOULLI_SYM
         | BLOCK_SYM
         | BODY_MARIADB_SYM
         | BTREE_SYM
diff --git a/sql/table.h b/sql/table.h
index c944ac076cb..35751fd058c 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -65,6 +65,7 @@ class Pushdown_derived;
 struct Name_resolution_context;
 class Table_function_json_table;
 class Open_table_context;
+class Statistic_collector;
 
 /*
   Used to identify NESTED_JOIN structures within a join (applicable only to
@@ -1516,7 +1517,7 @@ struct TABLE
   /* used in RBR Triggers */
   bool master_had_triggers;
 #endif
-  Item *tablesample;
+  Statistic_collector *tablesample;
   REGINFO reginfo;			/* field connections */
   MEM_ROOT mem_root;
   /**
@@ -2267,7 +2268,7 @@ struct TABLE_LIST
     *last_ptr= &next_global;
     for_insert_data= insert_data;
   }
-  Item *tablesample;
+  Statistic_collector *tablesample;
 
   /*
     List of tables local to a subquery (used by SQL_I_List). Considers
