diff options
-rw-r--r-- | sql/handler.h | 3 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/records.cc | 24 | ||||
-rw-r--r-- | sql/records.h | 1 | ||||
-rw-r--r-- | sql/sql_base.cc | 6 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 14 | ||||
-rw-r--r-- | sql/table.cc | 19 | ||||
-rw-r--r-- | sql/table.h | 6 |
8 files changed, 68 insertions, 6 deletions
diff --git a/sql/handler.h b/sql/handler.h index c3f2908daf8..278af13857d 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3531,7 +3531,8 @@ public: /* 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 @@ public: /* 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 |