Created
May 20, 2022 17:40
-
-
Save spetrunia/79fcd31c8fe114479a77e682df211c4c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/sql/handler.h b/sql/handler.h | |
index d38c3da8da1..44255efab98 100644 | |
--- a/sql/handler.h | |
+++ b/sql/handler.h | |
@@ -3532,7 +3532,8 @@ class handler :public Sql_alloc | |
/* this is necessary in many places, e.g. in HANDLER command */ | |
int ha_index_or_rnd_end() | |
{ | |
- return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0; | |
+ return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : | |
+ inited == SAMPLING? ha_sample_end(): 0; | |
} | |
/** | |
The cached_table_flags is set at ha_open and ha_external_lock | |
diff --git a/sql/lex.h b/sql/lex.h | |
index 4ce88ccc2ee..55589d888e6 100644 | |
--- a/sql/lex.h | |
+++ b/sql/lex.h | |
@@ -659,6 +659,7 @@ SYMBOL symbols[] = { | |
{ "TABLE", SYM(TABLE_SYM)}, | |
{ "TABLE_NAME", SYM(TABLE_NAME_SYM)}, | |
{ "TABLES", SYM(TABLES)}, | |
+ { "TABLESAMPLE", SYM(TABLESAMPLE)}, | |
{ "TABLESPACE", SYM(TABLESPACE)}, | |
{ "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)}, | |
{ "TEMPORARY", SYM(TEMPORARY)}, | |
diff --git a/sql/records.cc b/sql/records.cc | |
index b3b69f19665..9eadf788585 100644 | |
--- a/sql/records.cc | |
+++ b/sql/records.cc | |
@@ -37,6 +37,7 @@ | |
static int rr_quick(READ_RECORD *info); | |
int rr_sequential(READ_RECORD *info); | |
+int rr_sequential_sample(READ_RECORD *info); | |
static int rr_from_tempfile(READ_RECORD *info); | |
template<bool> static int rr_unpack_from_tempfile(READ_RECORD *info); | |
template<bool,bool> static int rr_unpack_from_buffer(READ_RECORD *info); | |
@@ -321,6 +322,14 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, | |
DBUG_RETURN(1); | |
} | |
} | |
+ else if (table->tablesample) | |
+ { | |
+ double fract= table->tablesample->val_real() / 100.0; | |
+ info->sample_counter= (ha_rows)(table->file->records() * fract + 0.5); | |
+ info->read_record_func= rr_sequential_sample; | |
+ if (table->file->ha_sample_init()) | |
+ DBUG_RETURN(1); | |
+ } | |
else | |
{ | |
DBUG_PRINT("info",("using rr_sequential")); | |
@@ -524,6 +533,21 @@ int rr_sequential(READ_RECORD *info) | |
return tmp; | |
} | |
+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; | |
+} | |
+ | |
static int rr_from_tempfile(READ_RECORD *info) | |
{ | |
diff --git a/sql/records.h b/sql/records.h | |
index 9bc1b98fde4..579e0e2bf3a 100644 | |
--- a/sql/records.h | |
+++ b/sql/records.h | |
@@ -61,6 +61,7 @@ struct READ_RECORD | |
SQL_SELECT *select; | |
uint ref_length, reclength, rec_cache_size, error_offset; | |
+ ha_rows sample_counter; | |
/** | |
Counting records when reading result from filesort(). | |
Used when filesort leaves the result in the filesort buffer. | |
diff --git a/sql/sql_base.cc b/sql/sql_base.cc | |
index 78d367e4005..4ced89e7c44 100644 | |
--- a/sql/sql_base.cc | |
+++ b/sql/sql_base.cc | |
@@ -7906,7 +7906,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context, | |
table->pos_in_table_list= table_list; | |
setup_table_map(table, table_list, tablenr); | |
- if (table_list->process_index_hints(table)) | |
+ if (table_list->process_index_hints(table) || | |
+ table_list->process_table_sample(table)) | |
DBUG_RETURN(1); | |
} | |
tablenr++; | |
@@ -7937,7 +7938,8 @@ bool setup_tables(THD *thd, Name_resolution_context *context, | |
table_list->table->map= table_list->map_exec; | |
table_list->table->maybe_null= table_list->maybe_null_exec; | |
table_list->table->pos_in_table_list= table_list; | |
- if (table_list->process_index_hints(table_list->table)) | |
+ if (table_list->process_index_hints(table_list->table) || | |
+ table_list->process_table_sample(table_list->table)) | |
DBUG_RETURN(1); | |
} | |
select_lex->leaf_tables.push_back(table_list); | |
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy | |
index c51345dcf26..88df2bc3d7a 100644 | |
--- a/sql/sql_yacc.yy | |
+++ b/sql/sql_yacc.yy | |
@@ -678,6 +678,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); | |
%token <kwd> SUM_SYM /* SQL-2003-N */ | |
%token <kwd> SYSDATE | |
%token <kwd> TABLE_REF_PRIORITY | |
+%token <kwd> TABLESAMPLE /* SQL-2016-R */ | |
%token <kwd> TABLE_SYM /* SQL-2003-R */ | |
%token <kwd> TERMINATED | |
%token <kwd> THEN_SYM /* SQL-2003-R */ | |
@@ -1498,7 +1499,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); | |
%type <item_param> param_marker | |
%type <item_num> | |
- NUM_literal | |
+ NUM_literal opt_table_sample | |
%type <item_basic_constant> text_literal | |
@@ -11700,10 +11701,19 @@ join_table_parens: | |
} | |
; | |
+/* psergey */ | |
+opt_table_sample: | |
+ /* empty */ { $$=0; } | |
+ | TABLESAMPLE SYSTEM '(' NUM_literal ')' | |
+ { | |
+ $$=$4; | |
+ } | |
+ ; | |
table_primary_ident: | |
table_ident opt_use_partition opt_for_system_time_clause | |
opt_table_alias_clause opt_key_definition | |
+ opt_table_sample | |
{ | |
if (!($$= Select->add_table_to_list(thd, $1, $4, | |
0, | |
@@ -11714,6 +11724,8 @@ table_primary_ident: | |
MYSQL_YYABORT; | |
if ($3) | |
$$->vers_conditions= Lex->vers_conditions; | |
+ if ($6) | |
+ $$->tablesample= $6; | |
} | |
; | |
diff --git a/sql/table.cc b/sql/table.cc | |
index 4e858cdb24c..4504e37dd7f 100644 | |
--- a/sql/table.cc | |
+++ b/sql/table.cc | |
@@ -5554,6 +5554,7 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) | |
opt_range_condition_rows=0; | |
no_cache= false; | |
initialize_opt_range_structures(); | |
+ tablesample= NULL; | |
#ifdef HAVE_REPLICATION | |
/* used in RBR Triggers */ | |
master_had_triggers= 0; | |
@@ -8531,6 +8532,24 @@ bool TABLE_LIST::process_index_hints(TABLE *tbl) | |
return 0; | |
} | |
+bool TABLE_LIST::process_table_sample(TABLE *tbl) | |
+{ | |
+ if (tablesample) | |
+ { | |
+ if (lock_type != TL_READ_DEFAULT) | |
+ { | |
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Updates to tables using sampling"); | |
+ return true; | |
+ } | |
+ tbl->keys_in_use_for_query.clear_all(); | |
+ tbl->keys_in_use_for_group_by.clear_all(); | |
+ tbl->keys_in_use_for_order_by.clear_all(); | |
+ tbl->covering_keys.clear_all(); | |
+ tbl->tablesample= tablesample; | |
+ } | |
+ return false; | |
+} | |
+ | |
size_t max_row_length(TABLE *table, MY_BITMAP const *cols, const uchar *data) | |
{ | |
diff --git a/sql/table.h b/sql/table.h | |
index 88216c788d4..5c0e7f9b51a 100644 | |
--- a/sql/table.h | |
+++ b/sql/table.h | |
@@ -1497,7 +1497,7 @@ struct TABLE | |
/* used in RBR Triggers */ | |
bool master_had_triggers; | |
#endif | |
- | |
+ Item *tablesample; | |
REGINFO reginfo; /* field connections */ | |
MEM_ROOT mem_root; | |
/** | |
@@ -2180,6 +2180,7 @@ struct TABLE_LIST | |
alias= (alias_arg ? *alias_arg : *table_name_arg); | |
lock_type= lock_type_arg; | |
updating= lock_type >= TL_FIRST_WRITE; | |
+ tablesample= NULL; | |
MDL_REQUEST_INIT(&mdl_request, MDL_key::TABLE, db.str, table_name.str, | |
mdl_type, MDL_TRANSACTION); | |
} | |
@@ -2221,7 +2222,7 @@ struct TABLE_LIST | |
*last_ptr= &next_global; | |
for_insert_data= insert_data; | |
} | |
- | |
+ Item *tablesample; | |
/* | |
List of tables local to a subquery (used by SQL_I_List). Considers | |
@@ -2724,6 +2725,7 @@ struct TABLE_LIST | |
TABLE::force_index and TABLE::covering_keys. | |
*/ | |
bool process_index_hints(TABLE *table); | |
+ bool process_table_sample(TABLE *tbl); | |
/** | |
Compare the version of metadata from the previous execution |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment