Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/myisam.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ extern int mi_rlast(struct st_myisam_info *file,uchar *buf,int inx);
extern int mi_rnext(struct st_myisam_info *file,uchar *buf,int inx);
extern int mi_rnext_same(struct st_myisam_info *info, uchar *buf);
extern int mi_rprev(struct st_myisam_info *file,uchar *buf,int inx);
extern int mi_random_dive(struct st_myisam_info *file, int inx, uchar *buf,
struct my_rnd_struct *rand_state);
extern int mi_rrnd(struct st_myisam_info *file,uchar *buf, my_off_t pos);
extern int mi_scan_init(struct st_myisam_info *file);
extern int mi_scan(struct st_myisam_info *file,uchar *buf);
Expand Down
1 change: 1 addition & 0 deletions libmysqld/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_show.cc ../sql/sql_state.c
../sql/sql_statistics.cc ../sql/sql_string.cc
../sql/sql_table.cc ../sql/sql_test.cc
../sql/sql_tablesample.cc
../sql/ddl_log.cc ../sql/item_vectorfunc.cc
../sql/sql_trigger.cc ../sql/sql_udf.cc ../sql/sql_union.cc
../sql/sql_update.cc ../sql/sql_view.cc ../sql/sql_profile.cc
Expand Down
151 changes: 151 additions & 0 deletions mysql-test/main/tablesample.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
DROP TABLE IF EXISTS t1, t2;
DROP VIEW IF EXISTS v1;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (b));
CREATE TABLE t2 (a INT, c INT);
CREATE VIEW v1 AS SELECT * FROM t1;
SELECT * FROM t1 TABLESAMPLE SYSTEM (10);
a b
SELECT * FROM t1 TABLESAMPLE BERNOULLI (50);
a b
SELECT * FROM t1 TABLESAMPLE SYSTEM (12.5);
a b
SELECT * FROM t1 TABLESAMPLE BERNOULLI (0.5);
a b
SELECT * FROM t1 TABLESAMPLE BERNOULLI (NULL);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL)' at line 1
SELECT * FROM t1 TABLESAMPLE NONEXISTENTMETHOD (12.5);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NONEXISTENTMETHOD (12.5)' at line 1
SELECT * FROM t1 TABLESAMPLE SYSTEM (-12.5);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-12.5)' at line 1
SELECT * FROM t1 TABLESAMPLE SYSTEM (10) JOIN t2 ON t1.a = t2.a;
a b a c
SELECT * FROM v1 TABLESAMPLE SYSTEM (20);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
PREPARE stmt2 FROM 'SELECT * FROM t1 TABLESAMPLE BERNOULLI (?)';
SET @pct = 30;
EXECUTE stmt2 USING @pct;
a b
SET @pct = 300;
EXECUTE stmt2 USING @pct;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
SET @pct = NULL;
EXECUTE stmt2 USING @pct;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
DEALLOCATE PREPARE stmt2;
DROP PROCEDURE IF EXISTS p1;
Warnings:
Note 1305 PROCEDURE test.p1 does not exist
CREATE PROCEDURE p1(IN sample_pct INT)
BEGIN
SELECT * FROM t1 TABLESAMPLE BERNOULLI (sample_pct);
END//
CALL p1(40);
a b
CALL p1(101);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
DROP PROCEDURE p1;
CREATE PROCEDURE p1(IN sample_pct DECIMAL)
BEGIN
SELECT * FROM t1 TABLESAMPLE SYSTEM (sample_pct);
END//
CALL p1(20.11);
a b
Warnings:
Note 1265 Data truncated for column 'sample_pct' at row 0
DROP PROCEDURE p1;
DROP PROCEDURE IF EXISTS p_char;
Warnings:
Note 1305 PROCEDURE test.p_char does not exist
CREATE PROCEDURE p_char(IN sample_pct CHAR(10))
BEGIN
SELECT * FROM t1 TABLESAMPLE SYSTEM (sample_pct);
END//
ERROR HY000: A variable of a non-numeric based type in TABLESAMPLE clause
DROP PROCEDURE IF EXISTS p_date;
Warnings:
Note 1305 PROCEDURE test.p_date does not exist
CREATE PROCEDURE p_date(IN sample_pct DATE)
BEGIN
SELECT * FROM t1 TABLESAMPLE BERNOULLI (sample_pct);
END//
ERROR HY000: A variable of a non-numeric based type in TABLESAMPLE clause
DROP PROCEDURE IF EXISTS p1;
Warnings:
Note 1305 PROCEDURE test.p1 does not exist
CREATE PROCEDURE p1()
BEGIN
DECLARE c SYS_REFCURSOR;
OPEN c FOR 'SELECT * FROM t1 TABLESAMPLE BERNOULLI (?)' USING NULL;
END//
CALL p1();
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
DROP PROCEDURE p1;
SELECT * FROM information_schema.tables TABLESAMPLE BERNOULLI (5);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
SELECT * FROM mysql.user TABLESAMPLE SYSTEM (10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
SELECT * FROM (SELECT * FROM t1) AS derived_tbl TABLESAMPLE SYSTEM (30);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'TABLESAMPLE SYSTEM (30)' at line 1
WITH cte_tbl AS (SELECT * FROM t1)
SELECT * FROM cte_tbl TABLESAMPLE BERNOULLI (10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
CREATE TABLE t_no_pk (a INT, b INT);
CREATE TABLE t_pk (a INT PRIMARY KEY, b INT);
SELECT * FROM t_no_pk TABLESAMPLE SYSTEM (10);
a b
Warnings:
Note 4272 TABLESAMPLE SYSTEM requires a primary key on table 't_no_pk'; using BERNOULLI sampling instead
SHOW WARNINGS;
Level Code Message
Note 4272 TABLESAMPLE SYSTEM requires a primary key on table 't_no_pk'; using BERNOULLI sampling instead
SELECT * FROM t_pk TABLESAMPLE SYSTEM (10);
a b
SHOW WARNINGS;
Level Code Message
SELECT * FROM t_pk TABLESAMPLE SYSTEM (30);
a b
SHOW WARNINGS;
Level Code Message
SELECT * FROM t_pk TABLESAMPLE SYSTEM (30.01);
a b
Warnings:
Note 4273 TABLESAMPLE SYSTEM on table 't_pk' requested more than 30% of rows; using BERNOULLI sampling instead
SHOW WARNINGS;
Level Code Message
Note 4273 TABLESAMPLE SYSTEM on table 't_pk' requested more than 30% of rows; using BERNOULLI sampling instead
SELECT * FROM t_pk TABLESAMPLE SYSTEM (50);
a b
Warnings:
Note 4273 TABLESAMPLE SYSTEM on table 't_pk' requested more than 30% of rows; using BERNOULLI sampling instead
SHOW WARNINGS;
Level Code Message
Note 4273 TABLESAMPLE SYSTEM on table 't_pk' requested more than 30% of rows; using BERNOULLI sampling instead
PREPARE stmt3 FROM 'SELECT * FROM t_no_pk TABLESAMPLE SYSTEM (10)';
Warnings:
Note 4272 TABLESAMPLE SYSTEM requires a primary key on table 't_no_pk'; using BERNOULLI sampling instead
EXECUTE stmt3;
a b
Warnings:
Note 4272 TABLESAMPLE SYSTEM requires a primary key on table 't_no_pk'; using BERNOULLI sampling instead
SHOW WARNINGS;
Level Code Message
Note 4272 TABLESAMPLE SYSTEM requires a primary key on table 't_no_pk'; using BERNOULLI sampling instead
ALTER TABLE t_no_pk ADD PRIMARY KEY (a);
EXECUTE stmt3;
a b
SHOW WARNINGS;
Level Code Message
DEALLOCATE PREPARE stmt3;
DROP TABLE t_no_pk, t_pk;
CREATE TABLE t_data (a INT PRIMARY KEY, b INT) ENGINE=MyISAM;
INSERT INTO t_data SELECT seq, seq * 2 FROM seq_1_to_20;
SET @save_join_cache_level= @@join_cache_level;
SET join_cache_level= 3;
EXPLAIN SELECT * FROM t_data AS t1 TABLESAMPLE BERNOULLI (20)
JOIN t_data AS t2 TABLESAMPLE BERNOULLI (30) ON t1.a = t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 sample NULL NULL NULL NULL 4
1 SIMPLE t2 hash_sample NULL #hash#$hj: 4: test.t1.a 6 Using where; Using join buffer (flat, BNLH join)
SET join_cache_level= @save_join_cache_level;
DROP TABLE t1, t2, t_data;
DROP VIEW v1;
221 changes: 221 additions & 0 deletions mysql-test/main/tablesample.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
#
# MDEV-38992 SQL Standard TABLESAMPLE clause
#
# For now, there are tests just for checking syntax
#

# TABLESAMPLE is not allowed on views, and the view-protocol's
# CREATE VIEW/SELECT/DROP VIEW rewriting of plain SELECTs clears the
# session's warning list between statements, breaking the SHOW WARNINGS
# checks below.
--source include/no_view_protocol.inc

--disable_warnings
DROP TABLE IF EXISTS t1, t2;
DROP VIEW IF EXISTS v1;
--enable_warnings

CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (b));
CREATE TABLE t2 (a INT, c INT);
CREATE VIEW v1 AS SELECT * FROM t1;

#
# Basic Syntax Validation
#
SELECT * FROM t1 TABLESAMPLE SYSTEM (10);
SELECT * FROM t1 TABLESAMPLE BERNOULLI (50);

SELECT * FROM t1 TABLESAMPLE SYSTEM (12.5);
SELECT * FROM t1 TABLESAMPLE BERNOULLI (0.5);

--error ER_PARSE_ERROR
SELECT * FROM t1 TABLESAMPLE BERNOULLI (NULL);

--error ER_PARSE_ERROR
SELECT * FROM t1 TABLESAMPLE NONEXISTENTMETHOD (12.5);

--error ER_PARSE_ERROR
SELECT * FROM t1 TABLESAMPLE SYSTEM (-12.5);

SELECT * FROM t1 TABLESAMPLE SYSTEM (10) JOIN t2 ON t1.a = t2.a;

--error ER_SYNTAX_ERROR
SELECT * FROM v1 TABLESAMPLE SYSTEM (20);

#
# Testing Prepared statements
#
PREPARE stmt2 FROM 'SELECT * FROM t1 TABLESAMPLE BERNOULLI (?)';

SET @pct = 30;
EXECUTE stmt2 USING @pct;

SET @pct = 300;
--error ER_SYNTAX_ERROR
EXECUTE stmt2 USING @pct;

SET @pct = NULL;
--error ER_SYNTAX_ERROR
EXECUTE stmt2 USING @pct;

DEALLOCATE PREPARE stmt2;

#
# Testing stored procedures
#
DROP PROCEDURE IF EXISTS p1;

DELIMITER //;
CREATE PROCEDURE p1(IN sample_pct INT)
BEGIN
SELECT * FROM t1 TABLESAMPLE BERNOULLI (sample_pct);
END//
DELIMITER ;//

CALL p1(40);

--error ER_SYNTAX_ERROR
CALL p1(101);

DROP PROCEDURE p1;

DELIMITER //;
CREATE PROCEDURE p1(IN sample_pct DECIMAL)
BEGIN
SELECT * FROM t1 TABLESAMPLE SYSTEM (sample_pct);
END//
DELIMITER ;//

CALL p1(20.11);

DROP PROCEDURE p1;

DROP PROCEDURE IF EXISTS p_char;

DELIMITER //;
--error ER_WRONG_SPVAR_TYPE_IN_TABLESAMPLE
CREATE PROCEDURE p_char(IN sample_pct CHAR(10))
BEGIN
SELECT * FROM t1 TABLESAMPLE SYSTEM (sample_pct);
END//
DELIMITER ;//

DROP PROCEDURE IF EXISTS p_date;

DELIMITER //;
--error ER_WRONG_SPVAR_TYPE_IN_TABLESAMPLE
CREATE PROCEDURE p_date(IN sample_pct DATE)
BEGIN
SELECT * FROM t1 TABLESAMPLE BERNOULLI (sample_pct);
END//
DELIMITER ;//

DROP PROCEDURE IF EXISTS p1;

DELIMITER //;
CREATE PROCEDURE p1()
BEGIN
DECLARE c SYS_REFCURSOR;
OPEN c FOR 'SELECT * FROM t1 TABLESAMPLE BERNOULLI (?)' USING NULL;
END//
DELIMITER ;//

--error ER_SYNTAX_ERROR
CALL p1();

DROP PROCEDURE p1;

#
# TABLESAMPLE should not work on system tables
#
--error ER_SYNTAX_ERROR
SELECT * FROM information_schema.tables TABLESAMPLE BERNOULLI (5);

--error ER_SYNTAX_ERROR
SELECT * FROM mysql.user TABLESAMPLE SYSTEM (10);

#
# TABLESAMPLE should not work on derived tables
#
--error ER_PARSE_ERROR
SELECT * FROM (SELECT * FROM t1) AS derived_tbl TABLESAMPLE SYSTEM (30);

--error ER_SYNTAX_ERROR
WITH cte_tbl AS (SELECT * FROM t1)
SELECT * FROM cte_tbl TABLESAMPLE BERNOULLI (10);

# INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10);
# INSERT INTO t2 VALUES (1, 1), (1, 2), (1, 3), (1, 4), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10);

# SELECT * FROM t1 TABLESAMPLE BERNOULLI (50);

# SELECT * FROM t1 TABLESAMPLE BERNOULLI (50) JOIN t2 TABLESAMPLE BERNOULLI (50) ON t1.a = t2.a;

#
# TABLESAMPLE SYSTEM without a primary key falls back to BERNOULLI
#
CREATE TABLE t_no_pk (a INT, b INT);
CREATE TABLE t_pk (a INT PRIMARY KEY, b INT);

SELECT * FROM t_no_pk TABLESAMPLE SYSTEM (10);
SHOW WARNINGS;

SELECT * FROM t_pk TABLESAMPLE SYSTEM (10);
SHOW WARNINGS;

#
# TABLESAMPLE SYSTEM with a sampling percentage above the
# SYSTEM_TO_BERNOULLI_MAX_FRACTION threshold falls back to
# BERNOULLI
#
SELECT * FROM t_pk TABLESAMPLE SYSTEM (30);
SHOW WARNINGS;

SELECT * FROM t_pk TABLESAMPLE SYSTEM (30.01);
SHOW WARNINGS;

SELECT * FROM t_pk TABLESAMPLE SYSTEM (50);
SHOW WARNINGS;

# Same parsed statement re-executed after the table's primary key changes:
# the fallback (and its warning) must reflect the CURRENT execution's table,
# not stick around from an earlier execution.
PREPARE stmt3 FROM 'SELECT * FROM t_no_pk TABLESAMPLE SYSTEM (10)';

EXECUTE stmt3;
SHOW WARNINGS;

ALTER TABLE t_no_pk ADD PRIMARY KEY (a);

EXECUTE stmt3;
SHOW WARNINGS;

DEALLOCATE PREPARE stmt3;
DROP TABLE t_no_pk, t_pk;

--source include/have_sequence.inc

CREATE TABLE t_data (a INT PRIMARY KEY, b INT) ENGINE=MyISAM;
INSERT INTO t_data SELECT seq, seq * 2 FROM seq_1_to_20;

# SELECT * FROM t_data TABLESAMPLE SYSTEM (20);

# SELECT * FROM t_data as t1 TABLESAMPLE BERNOULLI (20) JOIN t_data as t2 TABLESAMPLE BERNOULLI (30) ON t1.a = t2.a;

#
# A TABLESAMPLE'd table joined via hash join (BNLH) shows "hash_sample"
# in EXPLAIN, not the misleading "hash_ALL"
#
SET @save_join_cache_level= @@join_cache_level;
SET join_cache_level= 3;

EXPLAIN SELECT * FROM t_data AS t1 TABLESAMPLE BERNOULLI (20)
JOIN t_data AS t2 TABLESAMPLE BERNOULLI (30) ON t1.a = t2.a;

SET join_cache_level= @save_join_cache_level;

#
# Cleanup
#
DROP TABLE t1, t2, t_data;
DROP VIEW v1;
Loading