From cea395cb8d40c663e378983f4b2c434cad0430ab Mon Sep 17 00:00:00 2001
From: Robins Tharakan <robins@pobox.com>
Date: Sat, 16 Mar 2013 01:50:44 +0530
Subject: [PATCH] Add more regression tests for SEQUENCE

---
 src/test/regress/expected/sequence.out |  280 ++++++++++++++++++++++++++++++++
 src/test/regress/sql/sequence.sql      |  185 +++++++++++++++++++++
 2 files changed, 465 insertions(+)

diff --git a/src/test/regress/expected/sequence.out b/src/test/regress/expected/sequence.out
index 87feb08..cc7f432 100644
--- a/src/test/regress/expected/sequence.out
+++ b/src/test/regress/expected/sequence.out
@@ -372,6 +372,286 @@ REVOKE ALL ON seq3 FROM seq_user;
 SELECT lastval();
 ERROR:  permission denied for sequence seq3
 ROLLBACK;
+CREATE TABLE serialTest3 (f1 bigint, f2 bigint);
+-- Test SEQUENCE tied to a field
+CREATE SEQUENCE seq4 OWNED BY serialTest3.f1;
+ALTER TABLE serialTest3 DROP COLUMN f1;
+-- Should fail since seq4 shouldn't exit
+DROP SEQUENCE seq4;
+ERROR:  sequence "seq4" does not exist
+-- Should fail, unlogged sequences are currently not supported
+CREATE UNLOGGED SEQUENCE seq4 OWNED BY serialTest3.f1;
+ERROR:  unlogged sequences are not supported
+-- non-OWNER should not be allowed to access SEQUENCE 
+CREATE SEQUENCE seq4;
+SELECT nextval('seq4');
+ nextval 
+---------
+       1
+(1 row)
+
+CREATE USER tempdel;
+SET ROLE tempdel;
+SELECT nextval('seq4');
+ERROR:  permission denied for sequence seq4
+SELECT currval('seq4');
+ERROR:  permission denied for sequence seq4
+SELECT setval('seq4', 10);
+ERROR:  permission denied for sequence seq4
+ALTER SEQUENCE seq4 OWNED BY NONE;
+ERROR:  must be owner of relation seq4
+SELECT * FROM seq4;
+ERROR:  permission denied for relation seq4
+RESET ROLE;
+DROP ROLE tempdel;
+DROP SEQUENCE seq4;
+-- Should fail, Currval not yet defined in session
+CREATE SEQUENCE seq4;
+SELECT currval('seq4');
+ERROR:  currval of sequence "seq4" is not yet defined in this session
+DROP SEQUENCE seq4;
+-- Setval should work with valid values
+CREATE SEQUENCE seq4;
+SELECT setval('seq4', 10);
+ setval 
+--------
+     10
+(1 row)
+
+SELECT setval('seq4', 20, true);
+ setval 
+--------
+     20
+(1 row)
+
+SELECT setval('seq4', 30, false);
+ setval 
+--------
+     30
+(1 row)
+
+DROP SEQUENCE seq4;
+-- Should fail, setval beyond limits
+CREATE SEQUENCE seq4 MINVALUE 20 MAXVALUE 30;
+SELECT setval('seq4', 40);
+ERROR:  setval: value 40 is out of bounds for sequence "seq4" (20..30)
+SELECT setval('seq4', 10);
+ERROR:  setval: value 10 is out of bounds for sequence "seq4" (20..30)
+DROP SEQUENCE seq4;
+-- Should fail, trying a SEQUENCE function on a valid but non-SEQUENCE object
+SELECT nextval('serialTest3');
+ERROR:  "serialtest3" is not a sequence
+-- Should fail, crosscheck min/max
+CREATE SEQUENCE seq4 MINVALUE 40 MAXVALUE 30;
+ERROR:  MINVALUE (40) must be less than MAXVALUE (30)
+CREATE SEQUENCE seq4 MINVALUE 40 MAXVALUE 20 INCREMENT BY -1;
+ERROR:  MINVALUE (40) must be less than MAXVALUE (20)
+-- Should fail, crosscheck START with min/max
+CREATE SEQUENCE seq4 START 20 MINVALUE 30 MAXVALUE 40;
+ERROR:  START value (20) cannot be less than MINVALUE (30)
+CREATE SEQUENCE seq4 START -50 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+ERROR:  START value (-50) cannot be less than MINVALUE (-40)
+CREATE SEQUENCE seq4 START 50 MINVALUE 30 MAXVALUE 40;
+ERROR:  START value (50) cannot be greater than MAXVALUE (40)
+CREATE SEQUENCE seq4 START -20 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+ERROR:  START value (-20) cannot be greater than MAXVALUE (-30)
+-- Should work, ensure valid START works with valid min/max
+CREATE SEQUENCE seq4 START 35 MINVALUE 30 MAXVALUE 40;
+DROP SEQUENCE seq4;
+CREATE SEQUENCE seq4 START -35 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+DROP SEQUENCE seq4;
+-- Should fail, crosscheck RESTART with min/max
+CREATE SEQUENCE seq4 RESTART 20 MINVALUE 30 MAXVALUE 40;
+ERROR:  RESTART value (20) cannot be less than MINVALUE (30)
+CREATE SEQUENCE seq4 RESTART -50 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+ERROR:  RESTART value (-50) cannot be less than MINVALUE (-40)
+CREATE SEQUENCE seq4 RESTART 50 MINVALUE 30 MAXVALUE 40;
+ERROR:  RESTART value (50) cannot be greater than MAXVALUE (40)
+CREATE SEQUENCE seq4 RESTART -20 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+ERROR:  RESTART value (-20) cannot be greater than MAXVALUE (-30)
+-- Should work, ensure valid RESTART works with valid min/max
+CREATE SEQUENCE seq4 RESTART 35 MINVALUE 30 MAXVALUE 40;
+DROP SEQUENCE seq4;
+CREATE SEQUENCE seq4 RESTART -35 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+DROP SEQUENCE seq4;
+-- Should fail, Invalid OWNED BY option
+CREATE SEQUENCE seq4 OWNED BY asdf;
+ERROR:  invalid OWNED BY option
+HINT:  Specify OWNED BY table.column or OWNED BY NONE.
+CREATE SEQUENCE seq4 OWNED BY serialTest3;
+ERROR:  invalid OWNED BY option
+HINT:  Specify OWNED BY table.column or OWNED BY NONE.
+CREATE SEQUENCE seq4 OWNED BY serialTest3.asdf;
+ERROR:  column "asdf" of relation "serialtest3" does not exist
+CREATE SEQUENCE seq4;
+CREATE SEQUENCE seq5 OWNED BY seq4.asdf;
+ERROR:  referenced relation "seq4" is not a table
+DROP SEQUENCE seq4;
+-- Should fail, ensure table / sequence have same owner
+CREATE USER tempdel;
+SET ROLE tempdel;
+CREATE SEQUENCE seq5;
+ALTER SEQUENCE seq5 OWNED BY serialTest3.f1;
+ERROR:  sequence must have same owner as table it is linked to
+DROP SEQUENCE seq5;
+RESET ROLE;
+DROP ROLE tempdel;
+-- Should fail, ensure table / sequence have same schema
+CREATE SCHEMA tempdel;
+CREATE SEQUENCE tempdel.seq5;
+ALTER SEQUENCE tempdel.seq5 OWNED BY serialTest3.f1;
+ERROR:  sequence must be in same schema as table it is linked to
+DROP SEQUENCE tempdel.seq5;
+DROP SCHEMA tempdel;
+-- Should fail, INCREMENT BY cannot be 0
+CREATE SEQUENCE seq5 INCREMENT BY 0;
+ERROR:  INCREMENT must not be zero
+-- Check MAXVALUE in ALTER SEQUENCE
+CREATE SEQUENCE seq5 MINVALUE 1 MAXVALUE 2;
+ALTER SEQUENCE seq5 MINVALUE 0;
+SELECT nextval('seq5');
+ nextval 
+---------
+       1
+(1 row)
+
+SELECT nextval('seq5');
+ nextval 
+---------
+       2
+(1 row)
+
+SELECT nextval('seq5');
+ERROR:  nextval: reached maximum value of sequence "seq5" (2)
+ALTER SEQUENCE seq5 MAXVALUE 3;
+SELECT nextval('seq5');
+ nextval 
+---------
+       3
+(1 row)
+
+DROP SEQUENCE seq5;
+-- Check MINVALUE in ALTER SEQUENCE
+CREATE SEQUENCE seq5 MINVALUE 5 MAXVALUE 10;
+ALTER SEQUENCE seq5 MINVALUE 1;
+SELECT nextval('seq5');
+ nextval 
+---------
+       5
+(1 row)
+
+DROP SEQUENCE seq5;
+-- Should fail, Should not allow conflicting / Redundant options
+CREATE SEQUENCE seq5;
+ALTER SEQUENCE seq5 MAXVALUE 100 NO MAXVALUE;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 MINVALUE 100 NO MINVALUE;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 INCREMENT BY 1 INCREMENT BY -1;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 START 1 START 2;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 RESTART 1 RESTART 2;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 CACHE 1 CACHE 2;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 CYCLE NO CYCLE;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 OWNED BY NONE OWNED BY postgres;
+ERROR:  conflicting or redundant options
+ALTER SEQUENCE seq5 asdf;
+ERROR:  syntax error at or near "asdf"
+LINE 1: ALTER SEQUENCE seq5 asdf;
+                            ^
+DROP SEQUENCE seq5;
+-- Check NO MINVALUE
+CREATE SEQUENCE seq5 NO MINVALUE;
+ALTER SEQUENCE seq5 MINVALUE 1;
+SELECT nextval('seq5');
+ nextval 
+---------
+       1
+(1 row)
+
+DROP SEQUENCE seq5;
+-- Should work. Check that OWNED BY works as expected
+CREATE SEQUENCE seq5 OWNED BY serialTest3.f2;
+ALTER SEQUENCE seq5 OWNED BY NONE;
+DROP TABLE serialTest3;
+DROP SEQUENCE seq5;
+-- Should fail, Invalid CACHE value
+CREATE SEQUENCE seq6 CACHE 0;
+ERROR:  CACHE (0) must be greater than zero
+-- Ensure correct MAXVALUE for descending sequence. Also check valid CACHE value
+CREATE SEQUENCE seq7 INCREMENT -1 CACHE 2;
+SELECT nextval('seq7');
+ nextval 
+---------
+      -1
+(1 row)
+
+SELECT nextval('seq7');
+ nextval 
+---------
+      -2
+(1 row)
+
+DROP SEQUENCE seq7;
+-- Should stop incr when INCREMENT 1, CACHE > 1, MAXVALUE < 0, near MAXVALUE
+CREATE SEQUENCE seq8 INCREMENT 1 CACHE 3 MINVALUE -2 MAXVALUE -1;
+SELECT nextval('seq8');
+ nextval 
+---------
+      -2
+(1 row)
+
+SELECT nextval('seq8');
+ nextval 
+---------
+      -1
+(1 row)
+
+SELECT nextval('seq8');
+ERROR:  nextval: reached maximum value of sequence "seq8" (-1)
+DROP SEQUENCE seq8;
+-- Should stop decr when INCREMENT -1, CACHE > 1, MINVALUE > 0, near MINVALUE
+CREATE SEQUENCE seq9 INCREMENT -1 CACHE 3 MINVALUE 1 MAXVALUE 2;
+SELECT nextval('seq9');
+ nextval 
+---------
+       2
+(1 row)
+
+SELECT nextval('seq9');
+ nextval 
+---------
+       1
+(1 row)
+
+SELECT nextval('seq9');
+ERROR:  nextval: reached minimum value of sequence "seq9" (1)
+DROP SEQUENCE seq9;
+-- Should cycle when CYCLE is SET
+CREATE SEQUENCE seq10 CYCLE INCREMENT -1 MINVALUE 1 MAXVALUE 2;
+SELECT nextval('seq10');
+ nextval 
+---------
+       2
+(1 row)
+
+SELECT nextval('seq10');
+ nextval 
+---------
+       1
+(1 row)
+
+SELECT nextval('seq10');
+ nextval 
+---------
+       2
+(1 row)
+
+DROP SEQUENCE seq10;
 -- Sequences should get wiped out as well:
 DROP TABLE serialTest, serialTest2;
 -- Make sure sequences are gone:
diff --git a/src/test/regress/sql/sequence.sql b/src/test/regress/sql/sequence.sql
index a32e049..a41594c 100644
--- a/src/test/regress/sql/sequence.sql
+++ b/src/test/regress/sql/sequence.sql
@@ -171,6 +171,191 @@ REVOKE ALL ON seq3 FROM seq_user;
 SELECT lastval();
 ROLLBACK;
 
+CREATE TABLE serialTest3 (f1 bigint, f2 bigint);
+
+-- Test SEQUENCE tied to a field
+CREATE SEQUENCE seq4 OWNED BY serialTest3.f1;
+ALTER TABLE serialTest3 DROP COLUMN f1;
+
+-- Should fail since seq4 shouldn't exit
+DROP SEQUENCE seq4;
+
+-- Should fail, unlogged sequences are currently not supported
+CREATE UNLOGGED SEQUENCE seq4 OWNED BY serialTest3.f1;
+
+-- non-OWNER should not be allowed to access SEQUENCE 
+CREATE SEQUENCE seq4;
+SELECT nextval('seq4');
+CREATE USER tempdel;
+SET ROLE tempdel;
+SELECT nextval('seq4');
+SELECT currval('seq4');
+SELECT setval('seq4', 10);
+ALTER SEQUENCE seq4 OWNED BY NONE;
+SELECT * FROM seq4;
+RESET ROLE;
+DROP ROLE tempdel;
+DROP SEQUENCE seq4;
+
+-- non-OWNER when allowed to create SEQUENCE on table, should by OWNED by tbl owner
+CREATE USER tempdel;
+SET ROLE tempdel;
+CREATE TABLE tempTable1 (f1 bigint);
+RESET ROLE;
+ALTER TABLE tempTable1 ADD COLUMN f2 bigserial;
+SET ROLE tempdel;
+DROP TABLE tempTable1;
+RESET ROLE;
+DROP TABLE tempTable1;
+DROP ROLE tempdel;
+
+-- Should fail, Currval not yet defined in session
+CREATE SEQUENCE seq4;
+SELECT currval('seq4');
+DROP SEQUENCE seq4;
+
+-- Setval should work with valid values
+CREATE SEQUENCE seq4;
+SELECT setval('seq4', 10);
+SELECT setval('seq4', 20, true);
+SELECT setval('seq4', 30, false);
+DROP SEQUENCE seq4;
+
+-- Should fail, setval beyond limits
+CREATE SEQUENCE seq4 MINVALUE 20 MAXVALUE 30;
+SELECT setval('seq4', 40);
+SELECT setval('seq4', 10);
+DROP SEQUENCE seq4;
+
+-- Should fail, trying a SEQUENCE function on a valid but non-SEQUENCE object
+SELECT nextval('serialTest3');
+
+-- Should fail, crosscheck min/max
+CREATE SEQUENCE seq4 MINVALUE 40 MAXVALUE 30;
+CREATE SEQUENCE seq4 MINVALUE 40 MAXVALUE 20 INCREMENT BY -1;
+
+-- Should fail, crosscheck START with min/max
+CREATE SEQUENCE seq4 START 20 MINVALUE 30 MAXVALUE 40;
+CREATE SEQUENCE seq4 START -50 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+CREATE SEQUENCE seq4 START 50 MINVALUE 30 MAXVALUE 40;
+CREATE SEQUENCE seq4 START -20 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+
+-- Should work, ensure valid START works with valid min/max
+CREATE SEQUENCE seq4 START 35 MINVALUE 30 MAXVALUE 40;
+DROP SEQUENCE seq4;
+CREATE SEQUENCE seq4 START -35 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+DROP SEQUENCE seq4;
+
+-- Should fail, crosscheck RESTART with min/max
+CREATE SEQUENCE seq4 RESTART 20 MINVALUE 30 MAXVALUE 40;
+CREATE SEQUENCE seq4 RESTART -50 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+CREATE SEQUENCE seq4 RESTART 50 MINVALUE 30 MAXVALUE 40;
+CREATE SEQUENCE seq4 RESTART -20 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+
+-- Should work, ensure valid RESTART works with valid min/max
+CREATE SEQUENCE seq4 RESTART 35 MINVALUE 30 MAXVALUE 40;
+DROP SEQUENCE seq4;
+CREATE SEQUENCE seq4 RESTART -35 MINVALUE -40 MAXVALUE -30 INCREMENT BY -1;
+DROP SEQUENCE seq4;
+
+-- Should fail, Invalid OWNED BY option
+CREATE SEQUENCE seq4 OWNED BY asdf;
+CREATE SEQUENCE seq4 OWNED BY serialTest3;
+CREATE SEQUENCE seq4 OWNED BY serialTest3.asdf;
+CREATE SEQUENCE seq4;
+CREATE SEQUENCE seq5 OWNED BY seq4.asdf;
+DROP SEQUENCE seq4;
+
+-- Should fail, ensure table / sequence have same owner
+CREATE USER tempdel;
+SET ROLE tempdel;
+CREATE SEQUENCE seq5;
+ALTER SEQUENCE seq5 OWNED BY serialTest3.f1;
+DROP SEQUENCE seq5;
+RESET ROLE;
+DROP ROLE tempdel;
+
+-- Should fail, ensure table / sequence have same schema
+CREATE SCHEMA tempdel;
+CREATE SEQUENCE tempdel.seq5;
+ALTER SEQUENCE tempdel.seq5 OWNED BY serialTest3.f1;
+DROP SEQUENCE tempdel.seq5;
+DROP SCHEMA tempdel;
+
+-- Should fail, INCREMENT BY cannot be 0
+CREATE SEQUENCE seq5 INCREMENT BY 0;
+
+-- Check MAXVALUE in ALTER SEQUENCE
+CREATE SEQUENCE seq5 MINVALUE 1 MAXVALUE 2;
+ALTER SEQUENCE seq5 MINVALUE 0;
+SELECT nextval('seq5');
+SELECT nextval('seq5');
+SELECT nextval('seq5');
+ALTER SEQUENCE seq5 MAXVALUE 3;
+SELECT nextval('seq5');
+DROP SEQUENCE seq5;
+
+-- Check MINVALUE in ALTER SEQUENCE
+CREATE SEQUENCE seq5 MINVALUE 5 MAXVALUE 10;
+ALTER SEQUENCE seq5 MINVALUE 1;
+SELECT nextval('seq5');
+DROP SEQUENCE seq5;
+
+-- Should fail, Should not allow conflicting / Redundant options
+CREATE SEQUENCE seq5;
+ALTER SEQUENCE seq5 MAXVALUE 100 NO MAXVALUE;
+ALTER SEQUENCE seq5 MINVALUE 100 NO MINVALUE;
+ALTER SEQUENCE seq5 INCREMENT BY 1 INCREMENT BY -1;
+ALTER SEQUENCE seq5 START 1 START 2;
+ALTER SEQUENCE seq5 RESTART 1 RESTART 2;
+ALTER SEQUENCE seq5 CACHE 1 CACHE 2;
+ALTER SEQUENCE seq5 CYCLE NO CYCLE;
+ALTER SEQUENCE seq5 OWNED BY NONE OWNED BY postgres;
+ALTER SEQUENCE seq5 asdf;
+DROP SEQUENCE seq5;
+
+-- Check NO MINVALUE
+CREATE SEQUENCE seq5 NO MINVALUE;
+ALTER SEQUENCE seq5 MINVALUE 1;
+SELECT nextval('seq5');
+DROP SEQUENCE seq5;
+
+-- Should work. Check that OWNED BY works as expected
+CREATE SEQUENCE seq5 OWNED BY serialTest3.f2;
+ALTER SEQUENCE seq5 OWNED BY NONE;
+DROP TABLE serialTest3;
+DROP SEQUENCE seq5;
+
+-- Should fail, Invalid CACHE value
+CREATE SEQUENCE seq6 CACHE 0;
+
+-- Ensure correct MAXVALUE for descending sequence. Also check valid CACHE value
+CREATE SEQUENCE seq7 INCREMENT -1 CACHE 2;
+SELECT nextval('seq7');
+SELECT nextval('seq7');
+DROP SEQUENCE seq7;
+
+-- Should stop incr when INCREMENT 1, CACHE > 1, MAXVALUE < 0, near MAXVALUE
+CREATE SEQUENCE seq8 INCREMENT 1 CACHE 3 MINVALUE -2 MAXVALUE -1;
+SELECT nextval('seq8');
+SELECT nextval('seq8');
+SELECT nextval('seq8');
+DROP SEQUENCE seq8;
+
+-- Should stop decr when INCREMENT -1, CACHE > 1, MINVALUE > 0, near MINVALUE
+CREATE SEQUENCE seq9 INCREMENT -1 CACHE 3 MINVALUE 1 MAXVALUE 2;
+SELECT nextval('seq9');
+SELECT nextval('seq9');
+SELECT nextval('seq9');
+DROP SEQUENCE seq9;
+
+-- Should cycle when CYCLE is SET
+CREATE SEQUENCE seq10 CYCLE INCREMENT -1 MINVALUE 1 MAXVALUE 2;
+SELECT nextval('seq10');
+SELECT nextval('seq10');
+SELECT nextval('seq10');
+DROP SEQUENCE seq10;
+
 -- Sequences should get wiped out as well:
 DROP TABLE serialTest, serialTest2;
 
-- 
1.7.10.4

