--
-- Testing we handle transactions properly
--

CREATE TABLE t(a int, b int) USING columnar;

INSERT INTO t SELECT i, 2 * i FROM generate_series(1, 3) i;
SELECT * FROM t ORDER BY a;

-- verify that table rewrites work properly
BEGIN;
ALTER TABLE t ALTER COLUMN b TYPE float4 USING (b + 0.5)::float4;
INSERT INTO t VALUES (4, 8.5);
SELECT * FROM t ORDER BY a;
ROLLBACK;

SELECT * FROM t ORDER BY a;

-- verify truncate rollback
BEGIN;
TRUNCATE t;
INSERT INTO t VALUES (4, 8);
SELECT * FROM t ORDER BY a;
SAVEPOINT s1;
TRUNCATE t;
SELECT * FROM t ORDER BY a;
ROLLBACK TO SAVEPOINT s1;
SELECT * FROM t ORDER BY a;
ROLLBACK;

-- verify truncate with unflushed data in upper xacts
BEGIN;
INSERT INTO t VALUES (4, 8);
SAVEPOINT s1;
TRUNCATE t;
ROLLBACK TO SAVEPOINT s1;
COMMIT;

SELECT * FROM t ORDER BY a;

-- verify DROP TABLE rollback
BEGIN;
INSERT INTO t VALUES (5, 10);
SELECT * FROM t ORDER BY a;
SAVEPOINT s1;
DROP TABLE t;
SELECT * FROM t ORDER BY a;
ROLLBACK TO SAVEPOINT s1;
SELECT * FROM t ORDER BY a;
ROLLBACK;

-- verify DROP TABLE with unflushed data in upper xacts
BEGIN;
INSERT INTO t VALUES (5, 10);
SAVEPOINT s1;
DROP TABLE t;
SELECT * FROM t ORDER BY a;
ROLLBACK TO SAVEPOINT s1;
COMMIT;
SELECT * FROM t ORDER BY a;

-- verify SELECT when unflushed data in upper transactions errors.
BEGIN;
INSERT INTO t VALUES (6, 12);
SAVEPOINT s1;
SELECT * FROM t;
ROLLBACK;
SELECT * FROM t ORDER BY a;

--
-- Prepared transactions
--

BEGIN;
INSERT INTO t VALUES (6, 12);
INSERT INTO t VALUES (7, 14);
SELECT * FROM t ORDER BY a;
PREPARE TRANSACTION 'tx01';

SELECT * FROM t ORDER BY a;

ROLLBACK PREPARED 'tx01';

SELECT * FROM t ORDER BY a;

BEGIN;
INSERT INTO t VALUES (6, 13);
INSERT INTO t VALUES (7, 15);
PREPARE TRANSACTION 'tx02';

SELECT * FROM t ORDER BY a;

COMMIT PREPARED 'tx02';

SELECT * FROM t ORDER BY a;

--
-- Prepared statements
--

-- INSERT INTO with 0 params
PREPARE p0 AS INSERT INTO t VALUES (8, 8), (9, 9);
EXPLAIN (COSTS OFF) EXECUTE p0;
EXECUTE p0;
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p0;
SELECT * FROM t ORDER BY a;

-- INSERT INTO with 1 param
PREPARE p1(int) AS INSERT INTO t VALUES (10, $1), (11, $1+2);
EXPLAIN (COSTS OFF) EXECUTE p1(16);
EXECUTE p1(16);
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p1(20);
SELECT * FROM t ORDER BY a;

-- INSERT INTO with >1 params
PREPARE p2(int, int) AS INSERT INTO t VALUES (12, $1), (13, $1+2), (14, $2), ($1+1, $2+1);
EXPLAIN (COSTS OFF) EXECUTE p2(30, 40);
EXECUTE p2(30, 40);
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p2(50, 60);
SELECT * FROM t ORDER BY a;

-- SELECT with 0 params
PREPARE p3 AS SELECT * FROM t WHERE a = 8;
EXPLAIN (COSTS OFF) EXECUTE p3;
EXECUTE p3;
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p3;
SELECT * FROM t ORDER BY a;

-- SELECT with 1 param
PREPARE p5(int) AS SELECT * FROM t WHERE a = $1;
EXPLAIN (COSTS OFF) EXECUTE p5(16);
EXECUTE p5(16);
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p5(9);
SELECT * FROM t ORDER BY a;

-- SELECT with >1 params
PREPARE p6(int, int) AS SELECT * FROM t WHERE a = $1+1 AND b = $2+1;
EXPLAIN (COSTS OFF) EXECUTE p6(30, 40);
EXECUTE p6(30, 40);
EXPLAIN (ANALYZE true, COSTS off, TIMING off, SUMMARY off, BUFFERS OFF) EXECUTE p6(50, 60);
SELECT * FROM t ORDER BY a;

DROP TABLE t;
