\set VERBOSITY terse

SET search_path = 'public';
CREATE EXTENSION pg_pathman;
CREATE SCHEMA test_exprs;



/*
 * Test partitioning expression canonicalization process
 */

CREATE TABLE test_exprs.canon(c JSONB NOT NULL);
SELECT create_range_partitions('test_exprs.canon', '(C->>''key'')::int8', 1, 10, 2);
SELECT expr FROM pathman_config; /* check expression */
INSERT INTO test_exprs.canon VALUES ('{ "key": 2, "value": 0 }');
SELECT *, tableoid::REGCLASS FROM test_exprs.canon;
DROP TABLE test_exprs.canon CASCADE;


CREATE TABLE test_exprs.canon(val TEXT NOT NULL);
CREATE SEQUENCE test_exprs.canon_seq;
SELECT add_to_pathman_config('test_exprs.canon', 'VAL collate "C"', NULL);
SELECT add_range_partition('test_exprs.canon', 'a'::TEXT, 'b');
SELECT add_range_partition('test_exprs.canon', 'b'::TEXT, 'c');
SELECT add_range_partition('test_exprs.canon', 'c'::TEXT, 'd');
SELECT add_range_partition('test_exprs.canon', 'd'::TEXT, 'e');
SELECT expr FROM pathman_config; /* check expression */
INSERT INTO test_exprs.canon VALUES ('b');
SELECT *, tableoid::REGCLASS FROM test_exprs.canon;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.canon WHERE val COLLATE "C" < ALL (array['b', 'c']);
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.canon WHERE val COLLATE "POSIX" < ALL (array['b', 'c']);
DROP TABLE test_exprs.canon CASCADE;



/*
 * Test composite key.
 */
CREATE TABLE test_exprs.composite(a INT4 NOT NULL, b TEXT NOT NULL);
CREATE SEQUENCE test_exprs.composite_seq;
SELECT add_to_pathman_config('test_exprs.composite',
							 '(a, b)::test_exprs.composite',
							 NULL);
SELECT add_range_partition('test_exprs.composite',
						   '(1,a)'::test_exprs.composite,
						   '(10,a)'::test_exprs.composite);
SELECT add_range_partition('test_exprs.composite',
						   '(10,a)'::test_exprs.composite,
						   '(20,a)'::test_exprs.composite);
SELECT add_range_partition('test_exprs.composite',
						   '(20,a)'::test_exprs.composite,
						   '(30,a)'::test_exprs.composite);
SELECT add_range_partition('test_exprs.composite',
						   '(30,a)'::test_exprs.composite,
						   '(40,a)'::test_exprs.composite);
SELECT expr FROM pathman_config; /* check expression */
INSERT INTO test_exprs.composite VALUES(2,  'a');
INSERT INTO test_exprs.composite VALUES(11, 'a');
INSERT INTO test_exprs.composite VALUES(2,  'b');
INSERT INTO test_exprs.composite VALUES(50, 'b');
SELECT *, tableoid::REGCLASS FROM test_exprs.composite;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.composite WHERE (a, b)::test_exprs.composite < (21, 0)::test_exprs.composite;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.composite WHERE (a, b) < (21, 0)::test_exprs.composite;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.composite WHERE (a, b)::test_exprs.composite < (21, 0);
DROP TABLE test_exprs.composite CASCADE;


/* We use this rel to check 'pathman_hooks_enabled' */
CREATE TABLE test_exprs.canary(val INT4 NOT NULL);
CREATE TABLE test_exprs.canary_copy (LIKE test_exprs.canary);
SELECT create_hash_partitions('test_exprs.canary', 'val', 5);



/*
 * Test HASH
 */

CREATE TABLE test_exprs.hash_rel (
	id		SERIAL PRIMARY KEY,
	value	INTEGER NOT NULL,
	value2  INTEGER NOT NULL
);
INSERT INTO test_exprs.hash_rel (value, value2)
	SELECT val, val * 2 FROM generate_series(1, 5) val;

SELECT COUNT(*) FROM test_exprs.hash_rel;



\set VERBOSITY default

/* Try using constant expression */
SELECT create_hash_partitions('test_exprs.hash_rel', '1 + 1', 4);

/* Try using system attributes */
SELECT create_hash_partitions('test_exprs.hash_rel', 'xmin', 4);

/* Try using subqueries */
SELECT create_hash_partitions('test_exprs.hash_rel',
							  'value, (select oid from pg_class limit 1)',
							  4);

/* Try using mutable expression */
SELECT create_hash_partitions('test_exprs.hash_rel', 'random()', 4);

/* Try using broken parentheses */
SELECT create_hash_partitions('test_exprs.hash_rel', 'value * value2))', 4);

/* Try using missing columns */
SELECT create_hash_partitions('test_exprs.hash_rel', 'value * value3', 4);

/* Check that 'pathman_hooks_enabled' is true (1 partition in plan) */
EXPLAIN (COSTS OFF) INSERT INTO test_exprs.canary_copy
SELECT * FROM test_exprs.canary WHERE val = 1;

\set VERBOSITY terse


SELECT create_hash_partitions('test_exprs.hash_rel', 'value * value2', 4);
SELECT COUNT(*) FROM ONLY test_exprs.hash_rel;
SELECT COUNT(*) FROM test_exprs.hash_rel;

INSERT INTO test_exprs.hash_rel (value, value2)
	SELECT val, val * 2 FROM generate_series(6, 10) val;
SELECT COUNT(*) FROM ONLY test_exprs.hash_rel;
SELECT COUNT(*) FROM test_exprs.hash_rel;

EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.hash_rel WHERE value = 5;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.hash_rel WHERE (value * value2) = 5;



/*
 * Test RANGE
 */

CREATE TABLE test_exprs.range_rel (id SERIAL PRIMARY KEY, dt TIMESTAMP NOT NULL, txt TEXT);

INSERT INTO test_exprs.range_rel (dt, txt)
SELECT g, md5(g::TEXT) FROM generate_series('2015-01-01', '2020-04-30', '1 month'::interval) as g;



\set VERBOSITY default

/* Try using constant expression */
SELECT create_range_partitions('test_exprs.range_rel', '''16 years''::interval',
							   '15 years'::INTERVAL, '1 year'::INTERVAL, 10);

/* Try using mutable expression */
SELECT create_range_partitions('test_exprs.range_rel', 'RANDOM()',
							   '15 years'::INTERVAL, '1 year'::INTERVAL, 10);

/* Check that 'pathman_hooks_enabled' is true (1 partition in plan) */
EXPLAIN (COSTS OFF) INSERT INTO test_exprs.canary_copy
SELECT * FROM test_exprs.canary WHERE val = 1;

\set VERBOSITY terse


SELECT create_range_partitions('test_exprs.range_rel', 'AGE(dt, ''2000-01-01''::DATE)',
							   '15 years'::INTERVAL, '1 year'::INTERVAL, 10);
INSERT INTO test_exprs.range_rel_1 (dt, txt) VALUES ('2020-01-01'::DATE, md5('asdf'));
SELECT COUNT(*) FROM test_exprs.range_rel_6;
INSERT INTO test_exprs.range_rel_6 (dt, txt) VALUES ('2020-01-01'::DATE, md5('asdf'));
SELECT COUNT(*) FROM test_exprs.range_rel_6;
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.range_rel WHERE (AGE(dt, '2000-01-01'::DATE)) = '18 years'::interval;

SELECT create_update_triggers('test_exprs.range_rel');
SELECT COUNT(*) FROM test_exprs.range_rel;
SELECT COUNT(*) FROM test_exprs.range_rel_1;
SELECT COUNT(*) FROM test_exprs.range_rel_2;
UPDATE test_exprs.range_rel SET dt = '2016-12-01' WHERE dt >= '2015-10-10' AND dt <= '2017-10-10';

/* counts in partitions should be changed */
SELECT COUNT(*) FROM test_exprs.range_rel;
SELECT COUNT(*) FROM test_exprs.range_rel_1;
SELECT COUNT(*) FROM test_exprs.range_rel_2;


DROP SCHEMA test_exprs CASCADE;
DROP EXTENSION pg_pathman;
