You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by iw...@apache.org on 2016/08/30 01:48:27 UTC
incubator-hawq git commit: HAWQ-1015. Add feature test for
transactions with new test framework
Repository: incubator-hawq
Updated Branches:
refs/heads/master 27022e561 -> cb80c3331
HAWQ-1015. Add feature test for transactions with new test framework
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/cb80c333
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/cb80c333
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/cb80c333
Branch: refs/heads/master
Commit: cb80c333176e38a29eba618b70440b12f1b4ab33
Parents: 27022e5
Author: ivan <iw...@pivotal.io>
Authored: Mon Aug 29 11:01:31 2016 +0800
Committer: ivan <iw...@pivotal.io>
Committed: Tue Aug 30 09:46:28 2016 +0800
----------------------------------------------------------------------
.../feature/transactions/ans/transactions.ans | 558 +++++++++++++++++++
.../feature/transactions/sql/transactions.sql | 342 ++++++++++++
.../feature/transactions/test_transactions.cpp | 19 +
3 files changed, 919 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/cb80c333/src/test/feature/transactions/ans/transactions.ans
----------------------------------------------------------------------
diff --git a/src/test/feature/transactions/ans/transactions.ans b/src/test/feature/transactions/ans/transactions.ans
new file mode 100755
index 0000000..35669f4
--- /dev/null
+++ b/src/test/feature/transactions/ans/transactions.ans
@@ -0,0 +1,558 @@
+--
+-- TRANSACTIONS
+--
+CREATE TABLE aggtest (
+ a int2,
+ b float4
+);
+CREATE TABLE
+INSERT INTO aggtest VALUES (56, 7.8), (100, 99.097), (0, 0.09561), (42, 324.78);
+INSERT 0 4
+BEGIN;
+BEGIN
+SELECT *
+ INTO TABLE xacttest
+ FROM aggtest;
+SELECT 4
+INSERT INTO xacttest (a, b) VALUES (777, 777.777);
+INSERT 0 1
+END;
+COMMIT
+-- should retrieve one value--
+SELECT a FROM xacttest WHERE a > 100;
+ a
+-----
+ 777
+(1 row)
+
+BEGIN;
+BEGIN
+CREATE TABLE disappear (a int4);
+CREATE TABLE
+TRUNCATE aggtest;
+TRUNCATE TABLE
+-- should be empty
+SELECT * FROM aggtest;
+ a | b
+---+---
+(0 rows)
+
+ABORT;
+ROLLBACK
+-- should not exist
+SELECT oid FROM pg_class WHERE relname = 'disappear';
+ oid
+-----
+(0 rows)
+
+-- should have members again
+SELECT * FROM aggtest;
+ a | b
+-----+---------
+ 56 | 7.8
+ 100 | 99.097
+ 0 | 0.09561
+ 42 | 324.78
+(4 rows)
+
+drop table aggtest;
+DROP TABLE
+-- Read-only tests
+CREATE TABLE writetest (a int);
+CREATE TABLE
+CREATE TEMPORARY TABLE temptest (a int);
+CREATE TABLE
+SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;
+SET
+DROP TABLE writetest; -- fail
+psql:/tmp/TestTransaction_BasicTest.sql:56: ERROR: transaction is read-only
+INSERT INTO writetest VALUES (1); -- fail
+psql:/tmp/TestTransaction_BasicTest.sql:57: ERROR: transaction is read-only
+SELECT * FROM writetest; -- ok
+ a
+---
+(0 rows)
+
+-- DELETE FROM temptest; -- ok
+-- UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; -- ok
+-- PREPARE test AS INSERT INTO writetest VALUES (1); -- ok
+-- EXECUTE test; -- fail
+SELECT * FROM writetest, temptest; -- ok
+ a | a
+---+---
+(0 rows)
+
+CREATE TABLE test AS SELECT * FROM writetest; -- fail
+psql:/tmp/TestTransaction_BasicTest.sql:64: ERROR: transaction is read-only
+START TRANSACTION READ WRITE;
+START TRANSACTION
+DROP TABLE writetest; -- ok
+DROP TABLE
+COMMIT;
+COMMIT
+-- Subtransactions, basic tests
+-- create & drop tables
+SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;
+SET
+CREATE TABLE foobar (a int);
+CREATE TABLE
+BEGIN;
+BEGIN
+ CREATE TABLE foo (a int);
+CREATE TABLE
+ SAVEPOINT one;
+SAVEPOINT
+ DROP TABLE foo;
+DROP TABLE
+ CREATE TABLE bar (a int);
+CREATE TABLE
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ RELEASE SAVEPOINT one;
+RELEASE
+ SAVEPOINT two;
+SAVEPOINT
+ CREATE TABLE baz (a int);
+CREATE TABLE
+ RELEASE SAVEPOINT two;
+RELEASE
+ drop TABLE foobar;
+DROP TABLE
+ CREATE TABLE barbaz (a int);
+CREATE TABLE
+COMMIT;
+COMMIT
+-- should exist: barbaz, baz, foo
+SELECT * FROM foo; -- should be empty
+ a
+---
+(0 rows)
+
+SELECT * FROM bar; -- shouldn't exist
+psql:/tmp/TestTransaction_BasicTest.sql:89: ERROR: relation "bar" does not exist
+LINE 1: SELECT * FROM bar;
+ ^
+SELECT * FROM barbaz; -- should be empty
+ a
+---
+(0 rows)
+
+SELECT * FROM baz; -- should be empty
+ a
+---
+(0 rows)
+
+-- inserts
+BEGIN;
+BEGIN
+ INSERT INTO foo VALUES (1);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT into bar VALUES (1);
+psql:/tmp/TestTransaction_BasicTest.sql:97: ERROR: relation "bar" does not exist
+ ROLLBACK TO one;
+ROLLBACK
+ RELEASE SAVEPOINT one;
+RELEASE
+ SAVEPOINT two;
+SAVEPOINT
+ INSERT into barbaz VALUES (1);
+INSERT 0 1
+ RELEASE two;
+RELEASE
+ SAVEPOINT three;
+SAVEPOINT
+ SAVEPOINT four;
+SAVEPOINT
+ INSERT INTO foo VALUES (2);
+INSERT 0 1
+ RELEASE SAVEPOINT four;
+RELEASE
+ ROLLBACK TO SAVEPOINT three;
+ROLLBACK
+ RELEASE SAVEPOINT three;
+RELEASE
+ INSERT INTO foo VALUES (3);
+INSERT 0 1
+COMMIT;
+COMMIT
+SELECT * FROM foo; -- should have 1 and 3
+ a
+---
+ 1
+ 3
+(2 rows)
+
+SELECT * FROM barbaz; -- should have 1
+ a
+---
+ 1
+(1 row)
+
+-- test whole-tree commit
+BEGIN;
+BEGIN
+ SAVEPOINT one;
+SAVEPOINT
+ SELECT foo;
+psql:/tmp/TestTransaction_BasicTest.sql:117: ERROR: column "foo" does not exist
+LINE 1: SELECT foo;
+ ^
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ RELEASE SAVEPOINT one;
+RELEASE
+ SAVEPOINT two;
+SAVEPOINT
+ CREATE TABLE savepoints (a int);
+CREATE TABLE
+ SAVEPOINT three;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (1);
+INSERT 0 1
+ SAVEPOINT four;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (2);
+INSERT 0 1
+ SAVEPOINT five;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (3);
+INSERT 0 1
+ ROLLBACK TO SAVEPOINT five;
+ROLLBACK
+COMMIT;
+COMMIT
+COMMIT; -- should not be in a transaction block
+psql:/tmp/TestTransaction_BasicTest.sql:130: WARNING: there is no transaction in progress
+COMMIT
+SELECT * FROM savepoints;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+-- test whole-tree rollback
+BEGIN;
+BEGIN
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (23);
+INSERT 0 1
+ RELEASE SAVEPOINT one;
+RELEASE
+ SAVEPOINT two;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (24);
+INSERT 0 1
+ SAVEPOINT three;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (25);
+INSERT 0 1
+ROLLBACK;
+ROLLBACK
+COMMIT; -- should not be in a transaction block
+psql:/tmp/TestTransaction_BasicTest.sql:143: WARNING: there is no transaction in progress
+COMMIT
+
+SELECT * FROM savepoints ORDER BY 1;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+-- test whole-tree commit on an aborted subtransaction
+BEGIN;
+BEGIN
+ INSERT INTO savepoints VALUES (4);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (5);
+INSERT 0 1
+ SELECT foo;
+psql:/tmp/TestTransaction_BasicTest.sql:152: ERROR: column "foo" does not exist
+LINE 1: SELECT foo;
+ ^
+COMMIT;
+ROLLBACK
+SELECT * FROM savepoints ORDER BY 1;
+ a
+---
+ 1
+ 2
+(2 rows)
+
+BEGIN;
+BEGIN
+ INSERT INTO savepoints VALUES (6);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (7);
+INSERT 0 1
+ RELEASE SAVEPOINT one;
+RELEASE
+ INSERT INTO savepoints VALUES (8);
+INSERT 0 1
+COMMIT;
+COMMIT
+-- rows 6 and 8 should have been created by the same xact
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8;
+-- rows 6 and 7 should have been created by different xacts
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7;
+BEGIN;
+BEGIN
+ INSERT INTO savepoints VALUES (9);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (10);
+INSERT 0 1
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ INSERT INTO savepoints VALUES (11);
+INSERT 0 1
+COMMIT;
+COMMIT
+SELECT a FROM savepoints WHERE a in (9, 10, 11) ORDER BY 1;
+ a
+----
+ 9
+ 11
+(2 rows)
+
+-- rows 9 and 11 should have been created by different xacts
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11;
+BEGIN;
+BEGIN
+ INSERT INTO savepoints VALUES (12);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (13);
+INSERT 0 1
+ SAVEPOINT two;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (14);
+INSERT 0 1
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ INSERT INTO savepoints VALUES (15);
+INSERT 0 1
+ SAVEPOINT two;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (16);
+INSERT 0 1
+ SAVEPOINT three;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (17);
+INSERT 0 1
+COMMIT;
+COMMIT
+SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17 ORDER BY 1;
+ a
+----
+ 12
+ 15
+ 16
+ 17
+(4 rows)
+
+BEGIN;
+BEGIN
+ INSERT INTO savepoints VALUES (18);
+INSERT 0 1
+ SAVEPOINT one;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (19);
+INSERT 0 1
+ SAVEPOINT two;
+SAVEPOINT
+ INSERT INTO savepoints VALUES (20);
+INSERT 0 1
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ INSERT INTO savepoints VALUES (21);
+INSERT 0 1
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ INSERT INTO savepoints VALUES (22);
+INSERT 0 1
+COMMIT;
+COMMIT
+SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22 ORDER BY 1;
+ a
+----
+ 18
+ 22
+(2 rows)
+
+DROP TABLE savepoints;
+DROP TABLE
+-- only in a transaction block:
+SAVEPOINT one;
+psql:/tmp/TestTransaction_BasicTest.sql:210: ERROR: SAVEPOINT may only be used in transaction blocks
+ROLLBACK TO SAVEPOINT one;
+psql:/tmp/TestTransaction_BasicTest.sql:211: ERROR: ROLLBACK TO SAVEPOINT may only be used in transaction blocks
+RELEASE SAVEPOINT one;
+psql:/tmp/TestTransaction_BasicTest.sql:212: ERROR: RELEASE SAVEPOINT may only be used in transaction blocks
+-- Only "rollback to" allowed in aborted state
+BEGIN;
+BEGIN
+ SAVEPOINT one;
+SAVEPOINT
+ SELECT 0/0;
+psql:/tmp/TestTransaction_BasicTest.sql:217: ERROR: division by zero
+ SAVEPOINT two; -- ignored till the end of ...
+psql:/tmp/TestTransaction_BasicTest.sql:218: ERROR: current transaction is aborted, commands ignored until end of transaction block
+ RELEASE SAVEPOINT one; -- ignored till the end of ...
+psql:/tmp/TestTransaction_BasicTest.sql:219: ERROR: current transaction is aborted, commands ignored until end of transaction block
+ ROLLBACK TO SAVEPOINT one;
+ROLLBACK
+ SELECT 1;
+ ?column?
+----------
+ 1
+(1 row)
+
+COMMIT;
+COMMIT
+SELECT 1; -- this should work
+ ?column?
+----------
+ 1
+(1 row)
+
+-- check non-transactional behavior of cursors
+-- BEGIN;
+-- DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY 1;
+-- SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- RELEASE SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- CLOSE c;
+-- DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY 1;
+-- SAVEPOINT two;
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT two;
+-- -- c is now dead to the world ...
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT two;
+-- RELEASE SAVEPOINT two;
+-- FETCH 10 FROM c;
+-- COMMIT;
+--
+-- Check that "stable" functions are really stable. They should not be
+-- able to see the partial results of the calling query. (Ideally we would
+-- also check that they don't see commits of concurrent transactions, but
+-- that's a mite hard to do within the limitations of pg_regress.)
+--
+select * from xacttest;
+ a | b
+-----+---------
+ 56 | 7.8
+ 100 | 99.097
+ 0 | 0.09561
+ 42 | 324.78
+ 777 | 777.777
+(5 rows)
+
+-- create or replace function max_xacttest() returns smallint language sql as
+-- 'select max(a) from xacttest' stable;
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+-- But a volatile function can see the partial results of the calling query
+-- create or replace function max_xacttest() returns smallint language sql as
+-- 'select max(a) from xacttest' volatile;
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+-- Now the same test with plpgsql (since it depends on SPI which is different)
+-- create or replace function max_xacttest() returns smallint language plpgsql as
+-- 'begin return max(a) from xacttest; end' stable;
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+-- create or replace function max_xacttest() returns smallint language plpgsql as
+-- 'begin return max(a) from xacttest; end' volatile;
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+-- test case for problems with dropping an open relation during abort
+-- BEGIN;
+-- savepoint x;
+-- CREATE TABLE koju (a INT UNIQUE);
+-- INSERT INTO koju VALUES (1);
+-- INSERT INTO koju VALUES (1);
+-- rollback to x;
+-- CREATE TABLE koju (a INT UNIQUE);
+-- INSERT INTO koju VALUES (1);
+-- INSERT INTO koju VALUES (1);
+-- ROLLBACK;
+DROP TABLE foo;
+DROP TABLE
+DROP TABLE baz;
+DROP TABLE
+DROP TABLE barbaz;
+DROP TABLE
+-- verify that cursors created during an aborted subtransaction are
+-- closed, but that we do not rollback the effect of any FETCHs
+-- performed in the aborted subtransaction
+-- begin;
+-- savepoint x;
+-- create table abc (a int);
+-- insert into abc values (5);
+-- insert into abc values (10);
+-- declare foo cursor for select * from abc;
+-- fetch from foo;
+-- rollback to x;
+-- should fail
+-- fetch from foo;
+-- commit;
+-- begin;
+-- create table abc (a int);
+-- insert into abc values (5);
+-- insert into abc values (10);
+-- insert into abc values (15);
+-- declare foo cursor for select * from abc;
+-- fetch from foo;
+-- savepoint x;
+-- fetch from foo;
+-- rollback to x;
+-- fetch from foo;
+-- abort;
+-- tests for the "tid" type
+SELECT '(3, 3)'::tid = '(3, 4)'::tid;
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT '(3, 3)'::tid = '(3, 3)'::tid;
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT '(3, 3)'::tid <> '(3, 3)'::tid;
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT '(3, 3)'::tid <> '(3, 4)'::tid;
+ ?column?
+----------
+ t
+(1 row)
+
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/cb80c333/src/test/feature/transactions/sql/transactions.sql
----------------------------------------------------------------------
diff --git a/src/test/feature/transactions/sql/transactions.sql b/src/test/feature/transactions/sql/transactions.sql
new file mode 100644
index 0000000..45ded0d
--- /dev/null
+++ b/src/test/feature/transactions/sql/transactions.sql
@@ -0,0 +1,342 @@
+--
+-- TRANSACTIONS
+--
+
+CREATE TABLE aggtest (
+ a int2,
+ b float4
+);
+
+INSERT INTO aggtest VALUES (56, 7.8), (100, 99.097), (0, 0.09561), (42, 324.78);
+
+BEGIN;
+
+SELECT *
+ INTO TABLE xacttest
+ FROM aggtest;
+
+INSERT INTO xacttest (a, b) VALUES (777, 777.777);
+
+END;
+
+-- should retrieve one value--
+SELECT a FROM xacttest WHERE a > 100;
+
+
+BEGIN;
+
+CREATE TABLE disappear (a int4);
+
+TRUNCATE aggtest;
+
+-- should be empty
+SELECT * FROM aggtest;
+
+ABORT;
+
+-- should not exist
+SELECT oid FROM pg_class WHERE relname = 'disappear';
+
+-- should have members again
+SELECT * FROM aggtest;
+
+drop table aggtest;
+
+
+-- Read-only tests
+
+CREATE TABLE writetest (a int);
+CREATE TEMPORARY TABLE temptest (a int);
+
+SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY;
+
+DROP TABLE writetest; -- fail
+INSERT INTO writetest VALUES (1); -- fail
+SELECT * FROM writetest; -- ok
+-- DELETE FROM temptest; -- ok
+-- UPDATE temptest SET a = 0 FROM writetest WHERE temptest.a = 1 AND writetest.a = temptest.a; -- ok
+-- PREPARE test AS INSERT INTO writetest VALUES (1); -- ok
+-- EXECUTE test; -- fail
+SELECT * FROM writetest, temptest; -- ok
+CREATE TABLE test AS SELECT * FROM writetest; -- fail
+
+START TRANSACTION READ WRITE;
+DROP TABLE writetest; -- ok
+COMMIT;
+
+-- Subtransactions, basic tests
+-- create & drop tables
+SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE;
+CREATE TABLE foobar (a int);
+BEGIN;
+ CREATE TABLE foo (a int);
+ SAVEPOINT one;
+ DROP TABLE foo;
+ CREATE TABLE bar (a int);
+ ROLLBACK TO SAVEPOINT one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ CREATE TABLE baz (a int);
+ RELEASE SAVEPOINT two;
+ drop TABLE foobar;
+ CREATE TABLE barbaz (a int);
+COMMIT;
+-- should exist: barbaz, baz, foo
+SELECT * FROM foo; -- should be empty
+SELECT * FROM bar; -- shouldn't exist
+SELECT * FROM barbaz; -- should be empty
+SELECT * FROM baz; -- should be empty
+
+-- inserts
+BEGIN;
+ INSERT INTO foo VALUES (1);
+ SAVEPOINT one;
+ INSERT into bar VALUES (1);
+ ROLLBACK TO one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ INSERT into barbaz VALUES (1);
+ RELEASE two;
+ SAVEPOINT three;
+ SAVEPOINT four;
+ INSERT INTO foo VALUES (2);
+ RELEASE SAVEPOINT four;
+ ROLLBACK TO SAVEPOINT three;
+ RELEASE SAVEPOINT three;
+ INSERT INTO foo VALUES (3);
+COMMIT;
+SELECT * FROM foo; -- should have 1 and 3
+SELECT * FROM barbaz; -- should have 1
+
+-- test whole-tree commit
+BEGIN;
+ SAVEPOINT one;
+ SELECT foo;
+ ROLLBACK TO SAVEPOINT one;
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ CREATE TABLE savepoints (a int);
+ SAVEPOINT three;
+ INSERT INTO savepoints VALUES (1);
+ SAVEPOINT four;
+ INSERT INTO savepoints VALUES (2);
+ SAVEPOINT five;
+ INSERT INTO savepoints VALUES (3);
+ ROLLBACK TO SAVEPOINT five;
+COMMIT;
+COMMIT; -- should not be in a transaction block
+SELECT * FROM savepoints;
+
+-- test whole-tree rollback
+BEGIN;
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (23);
+ RELEASE SAVEPOINT one;
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (24);
+ SAVEPOINT three;
+ INSERT INTO savepoints VALUES (25);
+ROLLBACK;
+COMMIT; -- should not be in a transaction block
+
+SELECT * FROM savepoints ORDER BY 1;
+
+-- test whole-tree commit on an aborted subtransaction
+BEGIN;
+ INSERT INTO savepoints VALUES (4);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (5);
+ SELECT foo;
+COMMIT;
+SELECT * FROM savepoints ORDER BY 1;
+
+BEGIN;
+ INSERT INTO savepoints VALUES (6);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (7);
+ RELEASE SAVEPOINT one;
+ INSERT INTO savepoints VALUES (8);
+COMMIT;
+-- rows 6 and 8 should have been created by the same xact
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=8;
+-- rows 6 and 7 should have been created by different xacts
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=6 AND b.a=7;
+
+BEGIN;
+ INSERT INTO savepoints VALUES (9);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (10);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (11);
+COMMIT;
+SELECT a FROM savepoints WHERE a in (9, 10, 11) ORDER BY 1;
+-- rows 9 and 11 should have been created by different xacts
+-- SELECT a.xmin = b.xmin FROM savepoints a, savepoints b WHERE a.a=9 AND b.a=11;
+
+BEGIN;
+ INSERT INTO savepoints VALUES (12);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (13);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (14);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (15);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (16);
+ SAVEPOINT three;
+ INSERT INTO savepoints VALUES (17);
+COMMIT;
+SELECT a FROM savepoints WHERE a BETWEEN 12 AND 17 ORDER BY 1;
+
+BEGIN;
+ INSERT INTO savepoints VALUES (18);
+ SAVEPOINT one;
+ INSERT INTO savepoints VALUES (19);
+ SAVEPOINT two;
+ INSERT INTO savepoints VALUES (20);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (21);
+ ROLLBACK TO SAVEPOINT one;
+ INSERT INTO savepoints VALUES (22);
+COMMIT;
+SELECT a FROM savepoints WHERE a BETWEEN 18 AND 22 ORDER BY 1;
+
+DROP TABLE savepoints;
+
+-- only in a transaction block:
+SAVEPOINT one;
+ROLLBACK TO SAVEPOINT one;
+RELEASE SAVEPOINT one;
+
+-- Only "rollback to" allowed in aborted state
+BEGIN;
+ SAVEPOINT one;
+ SELECT 0/0;
+ SAVEPOINT two; -- ignored till the end of ...
+ RELEASE SAVEPOINT one; -- ignored till the end of ...
+ ROLLBACK TO SAVEPOINT one;
+ SELECT 1;
+COMMIT;
+SELECT 1; -- this should work
+
+-- check non-transactional behavior of cursors
+-- BEGIN;
+-- DECLARE c CURSOR FOR SELECT unique2 FROM tenk1 ORDER BY 1;
+-- SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- RELEASE SAVEPOINT one;
+-- FETCH 10 FROM c;
+-- CLOSE c;
+-- DECLARE c CURSOR FOR SELECT unique2/0 FROM tenk1 ORDER BY 1;
+-- SAVEPOINT two;
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT two;
+-- -- c is now dead to the world ...
+-- FETCH 10 FROM c;
+-- ROLLBACK TO SAVEPOINT two;
+-- RELEASE SAVEPOINT two;
+-- FETCH 10 FROM c;
+-- COMMIT;
+
+--
+-- Check that "stable" functions are really stable. They should not be
+-- able to see the partial results of the calling query. (Ideally we would
+-- also check that they don't see commits of concurrent transactions, but
+-- that's a mite hard to do within the limitations of pg_regress.)
+--
+select * from xacttest;
+
+-- create or replace function max_xacttest() returns smallint language sql as
+-- 'select max(a) from xacttest' stable;
+
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+
+-- But a volatile function can see the partial results of the calling query
+-- create or replace function max_xacttest() returns smallint language sql as
+-- 'select max(a) from xacttest' volatile;
+
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+
+-- Now the same test with plpgsql (since it depends on SPI which is different)
+-- create or replace function max_xacttest() returns smallint language plpgsql as
+-- 'begin return max(a) from xacttest; end' stable;
+
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+
+-- create or replace function max_xacttest() returns smallint language plpgsql as
+-- 'begin return max(a) from xacttest; end' volatile;
+
+-- begin;
+-- update xacttest set a = max_xacttest() + 10 where a > 0;
+-- select * from xacttest;
+-- rollback;
+
+
+-- test case for problems with dropping an open relation during abort
+-- BEGIN;
+-- savepoint x;
+-- CREATE TABLE koju (a INT UNIQUE);
+-- INSERT INTO koju VALUES (1);
+-- INSERT INTO koju VALUES (1);
+-- rollback to x;
+
+-- CREATE TABLE koju (a INT UNIQUE);
+-- INSERT INTO koju VALUES (1);
+-- INSERT INTO koju VALUES (1);
+-- ROLLBACK;
+
+DROP TABLE foo;
+DROP TABLE baz;
+DROP TABLE barbaz;
+
+-- verify that cursors created during an aborted subtransaction are
+-- closed, but that we do not rollback the effect of any FETCHs
+-- performed in the aborted subtransaction
+-- begin;
+
+-- savepoint x;
+-- create table abc (a int);
+-- insert into abc values (5);
+-- insert into abc values (10);
+-- declare foo cursor for select * from abc;
+-- fetch from foo;
+-- rollback to x;
+
+-- should fail
+-- fetch from foo;
+-- commit;
+
+-- begin;
+
+-- create table abc (a int);
+-- insert into abc values (5);
+-- insert into abc values (10);
+-- insert into abc values (15);
+-- declare foo cursor for select * from abc;
+
+-- fetch from foo;
+
+-- savepoint x;
+-- fetch from foo;
+-- rollback to x;
+
+-- fetch from foo;
+
+-- abort;
+
+-- tests for the "tid" type
+SELECT '(3, 3)'::tid = '(3, 4)'::tid;
+SELECT '(3, 3)'::tid = '(3, 3)'::tid;
+SELECT '(3, 3)'::tid <> '(3, 3)'::tid;
+SELECT '(3, 3)'::tid <> '(3, 4)'::tid;
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/cb80c333/src/test/feature/transactions/test_transactions.cpp
----------------------------------------------------------------------
diff --git a/src/test/feature/transactions/test_transactions.cpp b/src/test/feature/transactions/test_transactions.cpp
new file mode 100644
index 0000000..c3254da
--- /dev/null
+++ b/src/test/feature/transactions/test_transactions.cpp
@@ -0,0 +1,19 @@
+#include "gtest/gtest.h"
+
+#include "lib/sql_util.h"
+
+using std::string;
+
+class TestTransaction: public ::testing::Test
+{
+ public:
+ TestTransaction() { }
+ ~TestTransaction() {}
+};
+
+TEST_F(TestTransaction, BasicTest)
+{
+ hawq::test::SQLUtility util;
+ util.execSQLFile("transactions/sql/transactions.sql",
+ "transactions/ans/transactions.ans");
+}