|
| 1 | +#!/usr/bin/env python |
| 2 | +#coding: utf-8 |
| 3 | + |
| 4 | +import os |
| 5 | +import contextlib |
| 6 | +import sys |
| 7 | +import argparse |
| 8 | +import testgres |
| 9 | +import subprocess |
| 10 | +import difflib |
| 11 | + |
| 12 | +repo_dir = os.path.abspath(os.path.join('../..', os.path.dirname(__file__))) |
| 13 | + |
| 14 | +compilation = ''' |
| 15 | +make USE_PGXS=1 clean |
| 16 | +make USE_PGXS=1 install |
| 17 | +''' |
| 18 | + |
| 19 | +# just bunch of tables to create |
| 20 | +run_sql = ''' |
| 21 | +CREATE EXTENSION pg_pathman; |
| 22 | +
|
| 23 | +CREATE TABLE hash_rel ( |
| 24 | + id SERIAL PRIMARY KEY, |
| 25 | + value INTEGER NOT NULL); |
| 26 | +INSERT INTO hash_rel VALUES (1, 1); |
| 27 | +INSERT INTO hash_rel VALUES (2, 2); |
| 28 | +INSERT INTO hash_rel VALUES (3, 3); |
| 29 | +
|
| 30 | +SELECT create_hash_partitions('hash_rel', 'Value', 3); |
| 31 | +
|
| 32 | +CREATE TABLE range_rel ( |
| 33 | + id SERIAL PRIMARY KEY, |
| 34 | + dt TIMESTAMP, |
| 35 | + txt TEXT); |
| 36 | +CREATE INDEX ON range_rel (dt); |
| 37 | +INSERT INTO range_rel (dt, txt) |
| 38 | +SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) as g; |
| 39 | +SELECT create_range_partitions('range_rel', 'DT', '2015-01-01'::DATE, '1 month'::INTERVAL); |
| 40 | +
|
| 41 | +CREATE TABLE num_range_rel ( |
| 42 | + id SERIAL PRIMARY KEY, |
| 43 | + txt TEXT); |
| 44 | +SELECT create_range_partitions('num_range_rel', 'id', 0, 1000, 4); |
| 45 | +INSERT INTO num_range_rel |
| 46 | + SELECT g, md5(g::TEXT) FROM generate_series(1, 3000) as g; |
| 47 | +
|
| 48 | +CREATE TABLE improved_dummy_test1 (id BIGSERIAL, name TEXT NOT NULL); |
| 49 | +INSERT INTO improved_dummy_test1 (name) SELECT md5(g::TEXT) FROM generate_series(1, 100) as g; |
| 50 | +SELECT create_range_partitions('improved_dummy_test1', 'id', 1, 10); |
| 51 | +INSERT INTO improved_dummy_test1 (name) VALUES ('test'); /* spawns new partition */ |
| 52 | +ALTER TABLE improved_dummy_1 ADD CHECK (name != 'ib'); /* make improved_dummy_1 disappear */ |
| 53 | +
|
| 54 | +CREATE TABLE test_improved_dummy_test2 (val INT NOT NULL); |
| 55 | +SELECT create_range_partitions('test_improved_dummy_test2', 'val', |
| 56 | + generate_range_bounds(1, 1, 2), |
| 57 | + partition_names := '{p1, p2}'); |
| 58 | +
|
| 59 | +CREATE TABLE insert_into_select(val int NOT NULL); |
| 60 | +INSERT INTO insert_into_select SELECT generate_series(1, 100); |
| 61 | +SELECT create_range_partitions('insert_into_select', 'val', 1, 20); |
| 62 | +CREATE TABLE insert_into_select_copy (LIKE insert_into_select); /* INSERT INTO ... SELECT ... */ |
| 63 | +
|
| 64 | +# just a lot of actions |
| 65 | +
|
| 66 | +SELECT split_range_partition('num_range_rel_1', 500); |
| 67 | +SELECT split_range_partition('range_rel_1', '2015-01-15'::DATE); |
| 68 | +
|
| 69 | +/* Merge two partitions into one */ |
| 70 | +SELECT merge_range_partitions('num_range_rel_1', 'num_range_rel_' || currval('num_range_rel_seq')); |
| 71 | +SELECT merge_range_partitions('range_rel_1', 'range_rel_' || currval('range_rel_seq')); |
| 72 | +
|
| 73 | +/* Append and prepend partitions */ |
| 74 | +SELECT append_range_partition('num_range_rel'); |
| 75 | +SELECT prepend_range_partition('num_range_rel'); |
| 76 | +SELECT drop_range_partition('num_range_rel_7'); |
| 77 | +
|
| 78 | +SELECT drop_range_partition_expand_next('num_range_rel_4'); |
| 79 | +SELECT drop_range_partition_expand_next('num_range_rel_6'); |
| 80 | +
|
| 81 | +SELECT append_range_partition('range_rel'); |
| 82 | +SELECT prepend_range_partition('range_rel'); |
| 83 | +SELECT drop_range_partition('range_rel_7'); |
| 84 | +SELECT add_range_partition('range_rel', '2014-12-01'::DATE, '2015-01-02'::DATE); |
| 85 | +SELECT add_range_partition('range_rel', '2014-12-01'::DATE, '2015-01-01'::DATE); |
| 86 | +
|
| 87 | +CREATE TABLE range_rel_archive (LIKE range_rel INCLUDING ALL); |
| 88 | +SELECT attach_range_partition('range_rel', 'range_rel_archive', '2014-01-01'::DATE, '2015-01-01'::DATE); |
| 89 | +SELECT attach_range_partition('range_rel', 'range_rel_archive', '2014-01-01'::DATE, '2014-12-01'::DATE); |
| 90 | +SELECT detach_range_partition('range_rel_archive'); |
| 91 | +
|
| 92 | +CREATE TABLE range_rel_test1 ( |
| 93 | + id SERIAL PRIMARY KEY, |
| 94 | + dt TIMESTAMP, |
| 95 | + txt TEXT, |
| 96 | + abc INTEGER); |
| 97 | +SELECT attach_range_partition('range_rel', 'range_rel_test1', '2013-01-01'::DATE, '2014-01-01'::DATE); |
| 98 | +CREATE TABLE range_rel_test2 ( |
| 99 | + id SERIAL PRIMARY KEY, |
| 100 | + dt TIMESTAMP); |
| 101 | +SELECT attach_range_partition('range_rel', 'range_rel_test2', '2013-01-01'::DATE, '2014-01-01'::DATE); |
| 102 | +
|
| 103 | +/* Half open ranges */ |
| 104 | +SELECT add_range_partition('range_rel', NULL, '2014-12-01'::DATE, 'range_rel_minus_infinity'); |
| 105 | +SELECT add_range_partition('range_rel', '2015-06-01'::DATE, NULL, 'range_rel_plus_infinity'); |
| 106 | +SELECT append_range_partition('range_rel'); |
| 107 | +SELECT prepend_range_partition('range_rel'); |
| 108 | +
|
| 109 | +CREATE TABLE range_rel_minus_infinity (LIKE range_rel INCLUDING ALL); |
| 110 | +SELECT attach_range_partition('range_rel', 'range_rel_minus_infinity', NULL, '2014-12-01'::DATE); |
| 111 | +INSERT INTO range_rel (dt) VALUES ('2012-06-15'); |
| 112 | +INSERT INTO range_rel (dt) VALUES ('2015-12-15'); |
| 113 | +
|
| 114 | +CREATE TABLE zero( |
| 115 | + id SERIAL PRIMARY KEY, |
| 116 | + value INT NOT NULL); |
| 117 | +INSERT INTO zero SELECT g, g FROM generate_series(1, 100) as g; |
| 118 | +SELECT create_range_partitions('zero', 'value', 50, 10, 0); |
| 119 | +SELECT append_range_partition('zero', 'zero_0'); |
| 120 | +SELECT prepend_range_partition('zero', 'zero_1'); |
| 121 | +SELECT add_range_partition('zero', 50, 70, 'zero_50'); |
| 122 | +SELECT append_range_partition('zero', 'zero_appended'); |
| 123 | +SELECT prepend_range_partition('zero', 'zero_prepended'); |
| 124 | +SELECT split_range_partition('zero_50', 60, 'zero_60'); |
| 125 | +
|
| 126 | +CREATE TABLE hash_rel_extern (LIKE hash_rel INCLUDING ALL); |
| 127 | +SELECT replace_hash_partition('hash_rel_0', 'hash_rel_extern'); |
| 128 | +
|
| 129 | +-- automatic partitions creation |
| 130 | +CREATE TABLE range_rel_test1 ( |
| 131 | + id SERIAL PRIMARY KEY, |
| 132 | + dt TIMESTAMP NOT NULL, |
| 133 | + data TEXT); |
| 134 | +SELECT create_range_partitions('range_rel_test1', 'dt', '2015-01-01'::DATE, '10 days'::INTERVAL, 1); |
| 135 | +INSERT INTO range_rel_test1 (dt) |
| 136 | +SELECT generate_series('2015-01-01', '2015-04-30', '1 day'::interval); |
| 137 | +
|
| 138 | +INSERT INTO range_rel_test1 (dt) |
| 139 | +SELECT generate_series('2014-12-31', '2014-12-01', '-1 day'::interval); |
| 140 | +
|
| 141 | +/* CaMeL cAsE table names and attributes */ |
| 142 | +CREATE TABLE "TeSt" (a INT NOT NULL, b INT); |
| 143 | +SELECT create_hash_partitions('TeSt', 'a', 3); |
| 144 | +SELECT create_hash_partitions('"TeSt"', 'a', 3); |
| 145 | +INSERT INTO "TeSt" VALUES (1, 1); |
| 146 | +INSERT INTO "TeSt" VALUES (2, 2); |
| 147 | +INSERT INTO "TeSt" VALUES (3, 3); |
| 148 | +
|
| 149 | +CREATE TABLE "RangeRel" ( |
| 150 | + id SERIAL PRIMARY KEY, |
| 151 | + dt TIMESTAMP NOT NULL, |
| 152 | + txt TEXT); |
| 153 | +INSERT INTO "RangeRel" (dt, txt) |
| 154 | +SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2015-01-03', '1 day'::interval) as g; |
| 155 | +SELECT create_range_partitions('"RangeRel"', 'dt', '2015-01-01'::DATE, '1 day'::INTERVAL); |
| 156 | +SELECT append_range_partition('"RangeRel"'); |
| 157 | +SELECT prepend_range_partition('"RangeRel"'); |
| 158 | +SELECT merge_range_partitions('"RangeRel_1"', '"RangeRel_' || currval('"RangeRel_seq"') || '"'); |
| 159 | +SELECT split_range_partition('"RangeRel_1"', '2015-01-01'::DATE); |
| 160 | +
|
| 161 | +CREATE TABLE hash_rel_next1 ( |
| 162 | + id SERIAL PRIMARY KEY, |
| 163 | + value INTEGER NOT NULL); |
| 164 | +INSERT INTO hash_rel_next1 (value) SELECT g FROM generate_series(1, 10000) as g; |
| 165 | +SELECT create_hash_partitions('hash_rel_next1', 'value', 3); |
| 166 | +
|
| 167 | +CREATE TABLE range_rel_next1 ( |
| 168 | + id SERIAL PRIMARY KEY, |
| 169 | + dt TIMESTAMP NOT NULL, |
| 170 | + value INTEGER); |
| 171 | +INSERT INTO range_rel_next1 (dt, value) SELECT g, extract(day from g) FROM generate_series('2010-01-01'::date, '2010-12-31'::date, '1 day') as g; |
| 172 | +SELECT create_range_partitions('range_rel_next1', 'dt', '2010-01-01'::date, '1 month'::interval, 12); |
| 173 | +SELECT merge_range_partitions('range_rel_1', 'range_rel_2'); |
| 174 | +SELECT split_range_partition('range_rel_1', '2010-02-15'::date); |
| 175 | +SELECT append_range_partition('range_rel_next1'); |
| 176 | +SELECT prepend_range_partition('range_rel_next1'); |
| 177 | +''' |
| 178 | + |
| 179 | +@contextlib.contextmanager |
| 180 | +def cwd(path): |
| 181 | + print("cwd: ", path) |
| 182 | + curdir = os.getcwd() |
| 183 | + os.chdir(path) |
| 184 | + |
| 185 | + try: |
| 186 | + yield |
| 187 | + finally: |
| 188 | + print("cwd:", curdir) |
| 189 | + os.chdir(curdir) |
| 190 | + |
| 191 | +dump1_file = '/tmp/dump1.sql' |
| 192 | +dump2_file = '/tmp/dump2.sql' |
| 193 | + |
| 194 | +if __name__ == '__main__': |
| 195 | + parser = argparse.ArgumentParser(description='pg_pathman update checker') |
| 196 | + parser.add_argument('branches', nargs=2, |
| 197 | + help='specify branches ("main rel_1.5")') |
| 198 | + |
| 199 | + args = parser.parse_args() |
| 200 | + |
| 201 | + with open('dump_pathman_objects.sql') as f: |
| 202 | + dump_sql = f.read() |
| 203 | + |
| 204 | + with cwd(repo_dir): |
| 205 | + subprocess.check_output("git checkout %s" % args.branches[0], shell=True) |
| 206 | + subprocess.check_output(compilation, shell=True) |
| 207 | + |
| 208 | + with testgres.get_new_node('updated') as node: |
| 209 | + node.init() |
| 210 | + node.append_conf("shared_preload_libraries='pg_pathman'\n") |
| 211 | + |
| 212 | + node.start() |
| 213 | + node.safe_psql('postgres', run_sql) |
| 214 | + node.dump(dump1_file, 'postgres') |
| 215 | + node.stop() |
| 216 | + |
| 217 | + subprocess.check_output("git checkout %s" % args.branches[1], shell=True) |
| 218 | + subprocess.check_output(compilation, shell=True) |
| 219 | + |
| 220 | + version = None |
| 221 | + with open('pg_pathman.control') as f: |
| 222 | + for line in f.readlines(): |
| 223 | + if line.startswith('default_version'): |
| 224 | + version = line.split('=').strip() |
| 225 | + |
| 226 | + if version is None: |
| 227 | + print("cound not find version in second branch") |
| 228 | + exit(1) |
| 229 | + |
| 230 | + node.start() |
| 231 | + node.safe_psql("postgres", "alter extension pg_pathman update to %s" % version) |
| 232 | + dumped_objects_old = node.safe_psql("postgres", dump_sql) |
| 233 | + node.stop() |
| 234 | + |
| 235 | + # now make clean install |
| 236 | + with testgres.get_new_node('from_scratch') as node: |
| 237 | + node.init() |
| 238 | + node.append_conf("shared_preload_libraries='pg_pathman'\n") |
| 239 | + node.start() |
| 240 | + node.safe_psql('postgres', run_sql) |
| 241 | + dumped_objects_new = node.safe_psql("postgres", dump_sql) |
| 242 | + node.dump(dump2_file, 'postgres') |
| 243 | + |
| 244 | + # check dumps |
| 245 | + node.safe_psql('postgres', 'create database d1') |
| 246 | + node.restore(dump1_file, 'd1') |
| 247 | + |
| 248 | + node.safe_psql('postgres', 'create database d2') |
| 249 | + node.restore(dump2_file, 'd2') |
| 250 | + node.stop() |
| 251 | + |
| 252 | + if dumped_objects != dumped_objects_new: |
| 253 | + pass |
0 commit comments