3
-- Create ancillary data structures (i.e. indices)
9
CREATE INDEX onek_unique1 ON onek USING btree(unique1 int4_ops);
11
CREATE INDEX onek_unique2 ON onek USING btree(unique2 int4_ops);
13
CREATE INDEX onek_hundred ON onek USING btree(hundred int4_ops);
15
CREATE INDEX onek_stringu1 ON onek USING btree(stringu1 name_ops);
17
CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops);
19
CREATE INDEX tenk1_unique2 ON tenk1 USING btree(unique2 int4_ops);
21
CREATE INDEX tenk1_hundred ON tenk1 USING btree(hundred int4_ops);
23
CREATE INDEX tenk1_thous_tenthous ON tenk1 (thousand, tenthous);
25
CREATE INDEX tenk2_unique1 ON tenk2 USING btree(unique1 int4_ops);
27
CREATE INDEX tenk2_unique2 ON tenk2 USING btree(unique2 int4_ops);
29
CREATE INDEX tenk2_hundred ON tenk2 USING btree(hundred int4_ops);
31
CREATE INDEX rix ON road USING btree (name text_ops);
33
CREATE INDEX iix ON ihighway USING btree (name text_ops);
35
CREATE INDEX six ON shighway USING btree (name text_ops);
38
COMMENT ON INDEX six_wrong IS 'bad index';
39
COMMENT ON INDEX six IS 'good index';
40
COMMENT ON INDEX six IS NULL;
43
-- BTREE ascending/descending cases
45
-- we load int4/text from pure descending data (each key is a new
46
-- low key) and name/f8 from pure ascending data (each key is a new
47
-- high key). we had a bug where new low keys would sometimes be
50
CREATE INDEX bt_i4_index ON bt_i4_heap USING btree (seqno int4_ops);
52
CREATE INDEX bt_name_index ON bt_name_heap USING btree (seqno name_ops);
54
CREATE INDEX bt_txt_index ON bt_txt_heap USING btree (seqno text_ops);
56
CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops);
59
-- BTREE partial indices
61
CREATE INDEX onek2_u1_prtl ON onek2 USING btree(unique1 int4_ops)
62
where unique1 < 20 or unique1 > 980;
64
CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops)
67
CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
68
where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K';
71
-- GiST (rtree-equivalent opclasses only)
73
CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base);
75
CREATE INDEX gpolygonind ON polygon_tbl USING gist (f1);
77
CREATE INDEX gcircleind ON circle_tbl USING gist (f1);
79
INSERT INTO POINT_TBL(f1) VALUES (NULL);
81
CREATE INDEX gpointind ON point_tbl USING gist (f1);
83
CREATE TEMP TABLE gpolygon_tbl AS
84
SELECT polygon(home_base) AS f1 FROM slow_emp4000;
85
INSERT INTO gpolygon_tbl VALUES ( '(1000,0,0,1000)' );
86
INSERT INTO gpolygon_tbl VALUES ( '(0,1000,1000,1000)' );
88
CREATE TEMP TABLE gcircle_tbl AS
89
SELECT circle(home_base) AS f1 FROM slow_emp4000;
91
CREATE INDEX ggpolygonind ON gpolygon_tbl USING gist (f1);
93
CREATE INDEX ggcircleind ON gcircle_tbl USING gist (f1);
95
-- get non-indexed results for comparison purposes
97
SET enable_seqscan = ON;
98
SET enable_indexscan = OFF;
99
SET enable_bitmapscan = OFF;
101
SELECT * FROM fast_emp4000
102
WHERE home_base @ '(200,200),(2000,1000)'::box
103
ORDER BY (home_base[0])[0];
105
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
107
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
109
SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
110
ORDER BY (poly_center(f1))[0];
112
SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
115
SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
117
SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
119
SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
121
SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
123
SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
125
SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
127
SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
129
SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
131
SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
133
SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
135
SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
137
SELECT * FROM point_tbl ORDER BY f1 <-> '0,1';
139
SELECT * FROM point_tbl WHERE f1 IS NULL;
141
SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1';
143
SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
145
SET enable_seqscan = OFF;
146
SET enable_indexscan = ON;
147
SET enable_bitmapscan = ON;
150
SELECT * FROM fast_emp4000
151
WHERE home_base @ '(200,200),(2000,1000)'::box
152
ORDER BY (home_base[0])[0];
153
SELECT * FROM fast_emp4000
154
WHERE home_base @ '(200,200),(2000,1000)'::box
155
ORDER BY (home_base[0])[0];
158
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
159
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
162
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
163
SELECT count(*) FROM fast_emp4000 WHERE home_base IS NULL;
166
SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
167
ORDER BY (poly_center(f1))[0];
168
SELECT * FROM polygon_tbl WHERE f1 ~ '((1,1),(2,2),(2,1))'::polygon
169
ORDER BY (poly_center(f1))[0];
172
SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
174
SELECT * FROM circle_tbl WHERE f1 && circle(point(1,-2), 1)
178
SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
179
SELECT count(*) FROM gpolygon_tbl WHERE f1 && '(1000,1000,0,0)'::polygon;
182
SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
183
SELECT count(*) FROM gcircle_tbl WHERE f1 && '<(500,500),500>'::circle;
186
SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
187
SELECT count(*) FROM point_tbl WHERE f1 <@ box '(0,0,100,100)';
190
SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
191
SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
194
SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
195
SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
198
SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
199
SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
202
SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
203
SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
206
SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
207
SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
210
SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
211
SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
214
SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
215
SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
218
SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
219
SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
222
SELECT * FROM point_tbl ORDER BY f1 <-> '0,1';
223
SELECT * FROM point_tbl ORDER BY f1 <-> '0,1';
226
SELECT * FROM point_tbl WHERE f1 IS NULL;
227
SELECT * FROM point_tbl WHERE f1 IS NULL;
230
SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1';
231
SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1';
234
SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
235
SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
237
SET enable_seqscan = OFF;
238
SET enable_indexscan = OFF;
239
SET enable_bitmapscan = ON;
242
SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
243
SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
245
RESET enable_seqscan;
246
RESET enable_indexscan;
247
RESET enable_bitmapscan;
250
-- GIN over int[] and text[]
252
-- Note: GIN currently supports only bitmap scans, not plain indexscans
255
SET enable_seqscan = OFF;
256
SET enable_indexscan = OFF;
257
SET enable_bitmapscan = ON;
259
CREATE INDEX intarrayidx ON array_index_op_test USING gin (i);
262
SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno;
264
SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno;
265
SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno;
266
SELECT * FROM array_index_op_test WHERE i @> '{17}' ORDER BY seqno;
267
SELECT * FROM array_index_op_test WHERE i && '{17}' ORDER BY seqno;
268
SELECT * FROM array_index_op_test WHERE i @> '{32,17}' ORDER BY seqno;
269
SELECT * FROM array_index_op_test WHERE i && '{32,17}' ORDER BY seqno;
270
SELECT * FROM array_index_op_test WHERE i <@ '{38,34,32,89}' ORDER BY seqno;
271
SELECT * FROM array_index_op_test WHERE i = '{47,77}' ORDER BY seqno;
272
SELECT * FROM array_index_op_test WHERE i = '{}' ORDER BY seqno;
273
SELECT * FROM array_index_op_test WHERE i @> '{}' ORDER BY seqno;
274
SELECT * FROM array_index_op_test WHERE i && '{}' ORDER BY seqno;
275
SELECT * FROM array_index_op_test WHERE i <@ '{}' ORDER BY seqno;
276
SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno;
277
SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno;
278
SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno;
279
SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno;
281
CREATE INDEX textarrayidx ON array_index_op_test USING gin (t);
284
SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno;
286
SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno;
287
SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno;
288
SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno;
289
SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno;
290
SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno;
291
SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno;
292
SELECT * FROM array_index_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno;
293
SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno;
294
SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno;
295
SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno;
296
SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno;
297
SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno;
299
-- And try it with a multicolumn GIN index
301
DROP INDEX intarrayidx, textarrayidx;
303
CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t);
305
SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno;
306
SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno;
307
SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno;
308
SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno;
309
SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno;
310
SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno;
311
SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno;
312
SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno;
313
SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno;
315
RESET enable_seqscan;
316
RESET enable_indexscan;
317
RESET enable_bitmapscan;
322
CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops);
324
CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops);
326
CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops);
328
CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops);
330
-- CREATE INDEX hash_ovfl_index ON hash_ovfl_heap USING hash (x int4_ops);
334
-- Test functional index
336
CREATE TABLE func_index_heap (f1 text, f2 text);
337
CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2));
339
INSERT INTO func_index_heap VALUES('ABC','DEF');
340
INSERT INTO func_index_heap VALUES('AB','CDEFG');
341
INSERT INTO func_index_heap VALUES('QWE','RTY');
342
-- this should fail because of unique index:
343
INSERT INTO func_index_heap VALUES('ABCD', 'EF');
344
-- but this shouldn't:
345
INSERT INTO func_index_heap VALUES('QWERTY');
349
-- Same test, expressional index
351
DROP TABLE func_index_heap;
352
CREATE TABLE func_index_heap (f1 text, f2 text);
353
CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops);
355
INSERT INTO func_index_heap VALUES('ABC','DEF');
356
INSERT INTO func_index_heap VALUES('AB','CDEFG');
357
INSERT INTO func_index_heap VALUES('QWE','RTY');
358
-- this should fail because of unique index:
359
INSERT INTO func_index_heap VALUES('ABCD', 'EF');
360
-- but this shouldn't:
361
INSERT INTO func_index_heap VALUES('QWERTY');
364
-- Also try building functional, expressional, and partial indexes on
365
-- tables that already contain data.
367
create unique index hash_f8_index_1 on hash_f8_heap(abs(random));
368
create unique index hash_f8_index_2 on hash_f8_heap((seqno + 1), random);
369
create unique index hash_f8_index_3 on hash_f8_heap(random) where seqno > 1000;
372
-- Try some concurrent index builds
374
-- Unfortunately this only tests about half the code paths because there are
375
-- no concurrent updates happening to the table at the same time.
377
CREATE TABLE concur_heap (f1 text, f2 text);
379
CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1);
380
INSERT INTO concur_heap VALUES ('a','b');
381
INSERT INTO concur_heap VALUES ('b','b');
383
CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap(f1);
384
-- check if constraint is set up properly to be enforced
385
INSERT INTO concur_heap VALUES ('b','x');
386
-- check if constraint is enforced properly at build time
387
CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2);
388
-- test that expression indexes and partial indexes work concurrently
389
CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a';
390
CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x';
391
-- here we also check that you can default the index name
392
CREATE INDEX CONCURRENTLY on concur_heap((f2||f1));
394
-- You can't do a concurrent index build in a transaction
396
CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1);
399
-- But you can do a regular index build in a transaction
401
CREATE INDEX std_index on concur_heap(f2);
404
-- check to make sure that the failed indexes were cleaned up properly and the
405
-- successful indexes are created properly. Notably that they do NOT have the
406
-- "invalid" flag set.
410
DROP TABLE concur_heap;
413
-- Test ADD CONSTRAINT USING INDEX
416
CREATE TABLE cwi_test( a int , b varchar(10), c char);
418
-- add some data so that all tests have something to work with.
420
INSERT INTO cwi_test VALUES(1, 2), (3, 4), (5, 6);
422
CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test(a , b);
423
ALTER TABLE cwi_test ADD primary key USING INDEX cwi_uniq_idx;
427
CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a);
428
ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx,
429
ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY
430
USING INDEX cwi_uniq2_idx;
434
DROP INDEX cwi_replaced_pkey; -- Should fail; a constraint depends on it
439
-- Tests for IS NULL/IS NOT NULL with b-tree indexes
442
SELECT unique1, unique2 INTO onek_with_null FROM onek;
443
INSERT INTO onek_with_null (unique1,unique2) VALUES (NULL, -1), (NULL, NULL);
444
CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2,unique1);
446
SET enable_seqscan = OFF;
447
SET enable_indexscan = ON;
448
SET enable_bitmapscan = ON;
450
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL;
451
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL;
452
SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL;
453
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL;
455
DROP INDEX onek_nulltest;
457
CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc,unique1);
459
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL;
460
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL;
461
SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL;
462
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL;
464
DROP INDEX onek_nulltest;
466
CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc nulls last,unique1);
468
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL;
469
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL;
470
SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL;
471
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL;
473
DROP INDEX onek_nulltest;
475
CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 nulls first,unique1);
477
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL;
478
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL;
479
SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL;
480
SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL;
482
RESET enable_seqscan;
483
RESET enable_indexscan;
484
RESET enable_bitmapscan;
486
DROP TABLE onek_with_null;