1CREATE TABLE test_tablesample (id int, name text) WITH (fillfactor=10); 2-- use fillfactor so we don't have to load too much data to get multiple pages 3INSERT INTO test_tablesample 4 SELECT i, repeat(i::text, 200) FROM generate_series(0, 9) s(i); 5SELECT t.id FROM test_tablesample AS t TABLESAMPLE SYSTEM (50) REPEATABLE (0); 6 id 7---- 8 3 9 4 10 5 11 6 12 7 13 8 14(6 rows) 15 16SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (100.0/11) REPEATABLE (0); 17 id 18---- 19(0 rows) 20 21SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); 22 id 23---- 24 3 25 4 26 5 27 6 28 7 29 8 30(6 rows) 31 32SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (50) REPEATABLE (0); 33 id 34---- 35 4 36 5 37 6 38 7 39 8 40(5 rows) 41 42SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (5.5) REPEATABLE (0); 43 id 44---- 45 7 46(1 row) 47 48-- 100% should give repeatable count results (ie, all rows) in any case 49SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100); 50 count 51------- 52 10 53(1 row) 54 55SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (1+2); 56 count 57------- 58 10 59(1 row) 60 61SELECT count(*) FROM test_tablesample TABLESAMPLE SYSTEM (100) REPEATABLE (0.4); 62 count 63------- 64 10 65(1 row) 66 67CREATE VIEW test_tablesample_v1 AS 68 SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (10*2) REPEATABLE (2); 69CREATE VIEW test_tablesample_v2 AS 70 SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (99); 71\d+ test_tablesample_v1 72 View "public.test_tablesample_v1" 73 Column | Type | Collation | Nullable | Default | Storage | Description 74--------+---------+-----------+----------+---------+---------+------------- 75 id | integer | | | | plain | 76View definition: 77 SELECT test_tablesample.id 78 FROM test_tablesample TABLESAMPLE system ((10 * 2)) REPEATABLE (2); 79 80\d+ test_tablesample_v2 81 View "public.test_tablesample_v2" 82 Column | Type | Collation | Nullable | Default | Storage | Description 83--------+---------+-----------+----------+---------+---------+------------- 84 id | integer | | | | plain | 85View definition: 86 SELECT test_tablesample.id 87 FROM test_tablesample TABLESAMPLE system (99); 88 89-- check a sampled query doesn't affect cursor in progress 90BEGIN; 91DECLARE tablesample_cur CURSOR FOR 92 SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); 93FETCH FIRST FROM tablesample_cur; 94 id 95---- 96 3 97(1 row) 98 99FETCH NEXT FROM tablesample_cur; 100 id 101---- 102 4 103(1 row) 104 105FETCH NEXT FROM tablesample_cur; 106 id 107---- 108 5 109(1 row) 110 111SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (0); 112 id 113---- 114 3 115 4 116 5 117 6 118 7 119 8 120(6 rows) 121 122FETCH NEXT FROM tablesample_cur; 123 id 124---- 125 6 126(1 row) 127 128FETCH NEXT FROM tablesample_cur; 129 id 130---- 131 7 132(1 row) 133 134FETCH NEXT FROM tablesample_cur; 135 id 136---- 137 8 138(1 row) 139 140FETCH FIRST FROM tablesample_cur; 141 id 142---- 143 3 144(1 row) 145 146FETCH NEXT FROM tablesample_cur; 147 id 148---- 149 4 150(1 row) 151 152FETCH NEXT FROM tablesample_cur; 153 id 154---- 155 5 156(1 row) 157 158FETCH NEXT FROM tablesample_cur; 159 id 160---- 161 6 162(1 row) 163 164FETCH NEXT FROM tablesample_cur; 165 id 166---- 167 7 168(1 row) 169 170FETCH NEXT FROM tablesample_cur; 171 id 172---- 173 8 174(1 row) 175 176CLOSE tablesample_cur; 177END; 178EXPLAIN (COSTS OFF) 179 SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (2); 180 QUERY PLAN 181-------------------------------------------------------------------- 182 Sample Scan on test_tablesample 183 Sampling: system ('50'::real) REPEATABLE ('2'::double precision) 184(2 rows) 185 186EXPLAIN (COSTS OFF) 187 SELECT * FROM test_tablesample_v1; 188 QUERY PLAN 189-------------------------------------------------------------------- 190 Sample Scan on test_tablesample 191 Sampling: system ('20'::real) REPEATABLE ('2'::double precision) 192(2 rows) 193 194-- check inheritance behavior 195explain (costs off) 196 select count(*) from person tablesample bernoulli (100); 197 QUERY PLAN 198------------------------------------------------- 199 Aggregate 200 -> Append 201 -> Sample Scan on person person_1 202 Sampling: bernoulli ('100'::real) 203 -> Sample Scan on emp person_2 204 Sampling: bernoulli ('100'::real) 205 -> Sample Scan on student person_3 206 Sampling: bernoulli ('100'::real) 207 -> Sample Scan on stud_emp person_4 208 Sampling: bernoulli ('100'::real) 209(10 rows) 210 211select count(*) from person tablesample bernoulli (100); 212 count 213------- 214 58 215(1 row) 216 217select count(*) from person; 218 count 219------- 220 58 221(1 row) 222 223-- check that collations get assigned within the tablesample arguments 224SELECT count(*) FROM test_tablesample TABLESAMPLE bernoulli (('1'::text < '0'::text)::int); 225 count 226------- 227 0 228(1 row) 229 230-- check behavior during rescans, as well as correct handling of min/max pct 231select * from 232 (values (0),(100)) v(pct), 233 lateral (select count(*) from tenk1 tablesample bernoulli (pct)) ss; 234 pct | count 235-----+------- 236 0 | 0 237 100 | 10000 238(2 rows) 239 240select * from 241 (values (0),(100)) v(pct), 242 lateral (select count(*) from tenk1 tablesample system (pct)) ss; 243 pct | count 244-----+------- 245 0 | 0 246 100 | 10000 247(2 rows) 248 249explain (costs off) 250select pct, count(unique1) from 251 (values (0),(100)) v(pct), 252 lateral (select * from tenk1 tablesample bernoulli (pct)) ss 253 group by pct; 254 QUERY PLAN 255-------------------------------------------------------- 256 HashAggregate 257 Group Key: "*VALUES*".column1 258 -> Nested Loop 259 -> Values Scan on "*VALUES*" 260 -> Sample Scan on tenk1 261 Sampling: bernoulli ("*VALUES*".column1) 262(6 rows) 263 264select pct, count(unique1) from 265 (values (0),(100)) v(pct), 266 lateral (select * from tenk1 tablesample bernoulli (pct)) ss 267 group by pct; 268 pct | count 269-----+------- 270 100 | 10000 271(1 row) 272 273select pct, count(unique1) from 274 (values (0),(100)) v(pct), 275 lateral (select * from tenk1 tablesample system (pct)) ss 276 group by pct; 277 pct | count 278-----+------- 279 100 | 10000 280(1 row) 281 282-- errors 283SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1); 284ERROR: tablesample method foobar does not exist 285LINE 1: SELECT id FROM test_tablesample TABLESAMPLE FOOBAR (1); 286 ^ 287SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (NULL); 288ERROR: TABLESAMPLE parameter cannot be null 289SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (50) REPEATABLE (NULL); 290ERROR: TABLESAMPLE REPEATABLE parameter cannot be null 291SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (-1); 292ERROR: sample percentage must be between 0 and 100 293SELECT id FROM test_tablesample TABLESAMPLE BERNOULLI (200); 294ERROR: sample percentage must be between 0 and 100 295SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (-1); 296ERROR: sample percentage must be between 0 and 100 297SELECT id FROM test_tablesample TABLESAMPLE SYSTEM (200); 298ERROR: sample percentage must be between 0 and 100 299SELECT id FROM test_tablesample_v1 TABLESAMPLE BERNOULLI (1); 300ERROR: TABLESAMPLE clause can only be applied to tables and materialized views 301LINE 1: SELECT id FROM test_tablesample_v1 TABLESAMPLE BERNOULLI (1)... 302 ^ 303INSERT INTO test_tablesample_v1 VALUES(1); 304ERROR: cannot insert into view "test_tablesample_v1" 305DETAIL: Views containing TABLESAMPLE are not automatically updatable. 306HINT: To enable inserting into the view, provide an INSTEAD OF INSERT trigger or an unconditional ON INSERT DO INSTEAD rule. 307WITH query_select AS (SELECT * FROM test_tablesample) 308SELECT * FROM query_select TABLESAMPLE BERNOULLI (5.5) REPEATABLE (1); 309ERROR: TABLESAMPLE clause can only be applied to tables and materialized views 310LINE 2: SELECT * FROM query_select TABLESAMPLE BERNOULLI (5.5) REPEA... 311 ^ 312SELECT q.* FROM (SELECT * FROM test_tablesample) as q TABLESAMPLE BERNOULLI (5); 313ERROR: syntax error at or near "TABLESAMPLE" 314LINE 1: ...CT q.* FROM (SELECT * FROM test_tablesample) as q TABLESAMPL... 315 ^ 316-- check partitioned tables support tablesample 317create table parted_sample (a int) partition by list (a); 318create table parted_sample_1 partition of parted_sample for values in (1); 319create table parted_sample_2 partition of parted_sample for values in (2); 320explain (costs off) 321 select * from parted_sample tablesample bernoulli (100); 322 QUERY PLAN 323------------------------------------------- 324 Append 325 -> Sample Scan on parted_sample_1 326 Sampling: bernoulli ('100'::real) 327 -> Sample Scan on parted_sample_2 328 Sampling: bernoulli ('100'::real) 329(5 rows) 330 331drop table parted_sample, parted_sample_1, parted_sample_2; 332