openGauss-server/src/test/regress/expected/generated_col.out

953 lines
32 KiB
Plaintext

----------------------------------------------------------
---------------generated column test
----------------------------------------------------------
CREATE TABLE gtest0 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (55) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest0_pkey" for table "gtest0"
CREATE TABLE gtest1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest1_pkey" for table "gtest1"
SELECT table_name, column_name, column_default, is_nullable, is_generated, generation_expression FROM information_schema.columns WHERE table_name LIKE 'gtest_' ORDER BY 1, 2;
table_name | column_name | column_default | is_nullable | is_generated | generation_expression
------------+-------------+----------------+-------------+--------------+-----------------------
gtest0 | a | | NO | NEVER |
gtest0 | b | | YES | ALWAYS | 55
gtest1 | a | | NO | NEVER |
gtest1 | b | | YES | ALWAYS | (a * 2)
(4 rows)
\d gtest1
Table "public.gtest1"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer | not null
b | integer | generated always as ((a * 2)) stored
Indexes:
"gtest1_pkey" PRIMARY KEY, btree (a) TABLESPACE pg_default
-- duplicate generated
CREATE TABLE gtest_err_1 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ALWAYS AS (a * 3) STORED);
ERROR: multiple generation clauses specified for column "b" of table "gtest_err_1"
LINE 1: ...ARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED GENERATED ...
^
-- references to other generated columns, including self-references
CREATE TABLE gtest_err_2a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (b * 2) STORED);
ERROR: cannot use generated column "b" in column generation expression
DETAIL: A generated column cannot reference another generated column.
CREATE TABLE gtest_err_2b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED, c int GENERATED ALWAYS AS (b * 3) STORED);
ERROR: cannot use generated column "b" in column generation expression
DETAIL: A generated column cannot reference another generated column.
-- invalid reference
CREATE TABLE gtest_err_3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (c * 2) STORED);
ERROR: column "c" does not exist
-- generation expression must be immutable
CREATE TABLE gtest_err_4 (a int PRIMARY KEY, b double precision GENERATED ALWAYS AS (random()) STORED);
ERROR: generation expression is not immutable
-- cannot have default/identity and generated
CREATE TABLE gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ALWAYS AS (a * 2) STORED);
ERROR: both default and generation expression specified for column "b" of table "gtest_err_5a"
LINE 1: ... gtest_err_5a (a int PRIMARY KEY, b int DEFAULT 5 GENERATED ...
^
CREATE TABLE gtest_err_5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity GENERATED ALWAYS AS (a * 2) STORED);
ERROR: syntax error at or near "identity"
LINE 1: ..._5b (a int PRIMARY KEY, b int GENERATED ALWAYS AS identity G...
^
-- reference to system column not allowed in generated column
CREATE TABLE gtest_err_6a (a int PRIMARY KEY, b bool GENERATED ALWAYS AS (xmin <> 37) STORED);
ERROR: cannot use system column "xmin" in column generation expression
-- various prohibited constructs
CREATE TABLE gtest_err_7a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (avg(a)) STORED);
ERROR: cannot use aggregate function in generated column expression
CREATE TABLE gtest_err_7b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (row_number() OVER (ORDER BY a)) STORED);
ERROR: cannot use window function in generated column expression
CREATE TABLE gtest_err_7c (a int PRIMARY KEY, b int GENERATED ALWAYS AS ((SELECT a)) STORED);
ERROR: cannot use subquery in generated column expression
CREATE TABLE gtest_err_7d (a int PRIMARY KEY, b int GENERATED ALWAYS AS (generate_series(1, a)) STORED);
ERROR: generated column expression must not return a set
INSERT INTO gtest1 VALUES (1);
INSERT INTO gtest1 VALUES (2, DEFAULT);
INSERT INTO gtest1 VALUES (21, DEFAULT), (22, DEFAULT), (23, DEFAULT), (24, DEFAULT);
DELETE FROM gtest1 WHERE a >20;
INSERT INTO gtest1 VALUES (3, 33); -- error
ERROR: cannot insert into column "b"
DETAIL: Column "b" is a generated column.
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
1 | 2
2 | 4
(2 rows)
UPDATE gtest1 SET b = DEFAULT WHERE a = 1;
UPDATE gtest1 SET b = 11 WHERE a = 1; -- error
ERROR: column "b" can only be updated to DEFAULT
DETAIL: Column "b" is a generated column.
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
1 | 2
2 | 4
(2 rows)
SELECT a, b, b * 2 AS b2 FROM gtest1 ORDER BY a;
a | b | b2
---+---+----
1 | 2 | 4
2 | 4 | 8
(2 rows)
SELECT a, b FROM gtest1 WHERE b = 4 ORDER BY a;
a | b
---+---
2 | 4
(1 row)
-- test that overflow error happens on write
INSERT INTO gtest1 VALUES (2000000000);
ERROR: integer out of range
SELECT * FROM gtest1;
a | b
---+---
2 | 4
1 | 2
(2 rows)
DELETE FROM gtest1 WHERE a = 2000000000;
-- test with joins
CREATE TABLE gtestx (x int, y int);
INSERT INTO gtestx VALUES (11, 1), (22, 2), (33, 3);
SELECT * FROM gtestx, gtest1 WHERE gtestx.y = gtest1.a;
x | y | a | b
----+---+---+---
11 | 1 | 1 | 2
22 | 2 | 2 | 4
(2 rows)
DROP TABLE gtestx;
-- test UPDATE/DELETE quals
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
1 | 2
2 | 4
(2 rows)
UPDATE gtest1 SET a = 3 WHERE b = 4;
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
1 | 2
3 | 6
(2 rows)
DELETE FROM gtest1 WHERE b = 2;
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
3 | 6
(1 row)
-- views
CREATE VIEW gtest1v AS SELECT * FROM gtest1;
SELECT * FROM gtest1v;
a | b
---+---
3 | 6
(1 row)
INSERT INTO gtest1v VALUES (4, 8); -- fails
ERROR: cannot insert into view "gtest1v"
HINT: You need an unconditional ON INSERT DO INSTEAD rule or an INSTEAD OF INSERT trigger.
DROP VIEW gtest1v;
-- CTEs
WITH foo AS (SELECT * FROM gtest1) SELECT * FROM foo;
a | b
---+---
3 | 6
(1 row)
-- test stored update
CREATE TABLE gtest3 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 3) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest3_pkey" for table "gtest3"
INSERT INTO gtest3 (a) VALUES (1), (2), (3);
SELECT * FROM gtest3 ORDER BY a;
a | b
---+---
1 | 3
2 | 6
3 | 9
(3 rows)
UPDATE gtest3 SET a = 22 WHERE a = 2;
SELECT * FROM gtest3 ORDER BY a;
a | b
----+----
1 | 3
3 | 9
22 | 66
(3 rows)
-- COPY
TRUNCATE gtest1;
INSERT INTO gtest1 (a) VALUES (1), (2);
COPY gtest1 TO stdout;
1
2
COPY gtest1 (a, b) TO stdout;
ERROR: column "b" is a generated column
DETAIL: Generated columns cannot be used in COPY.
COPY gtest1 FROM stdin;
COPY gtest1 (a, b) FROM stdin;
ERROR: column "b" is a generated column
DETAIL: Generated columns cannot be used in COPY.
SELECT * FROM gtest1 ORDER BY a;
a | b
---+---
1 | 2
2 | 4
3 | 6
4 | 8
(4 rows)
TRUNCATE gtest3;
INSERT INTO gtest3 (a) VALUES (1), (2);
COPY gtest3 TO stdout;
1
2
COPY gtest3 (a, b) TO stdout;
ERROR: column "b" is a generated column
DETAIL: Generated columns cannot be used in COPY.
COPY gtest3 FROM stdin;
COPY gtest3 (a, b) FROM stdin;
ERROR: column "b" is a generated column
DETAIL: Generated columns cannot be used in COPY.
SELECT * FROM gtest3 ORDER BY a;
a | b
---+----
1 | 3
2 | 6
3 | 9
4 | 12
(4 rows)
-- null values
CREATE TABLE gtest2 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (NULL) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest2_pkey" for table "gtest2"
INSERT INTO gtest2 VALUES (1);
SELECT * FROM gtest2;
a | b
---+---
1 |
(1 row)
-- composite types
CREATE TYPE double_int as (a int, b int);
CREATE TABLE gtest4 (
a int,
b double_int GENERATED ALWAYS AS ((a * 2, a * 3)) STORED
);
INSERT INTO gtest4 VALUES (1), (6);
SELECT * FROM gtest4;
a | b
---+---------
1 | (2,3)
6 | (12,18)
(2 rows)
DROP TABLE gtest4;
DROP TYPE double_int;
-- using tableoid is allowed
CREATE TABLE gtest_tableoid (
a int PRIMARY KEY,
b bool GENERATED ALWAYS AS (tableoid <> 0) STORED
);
ERROR: cannot use system column "tableoid" in column generation expression
-- drop column behavior
CREATE TABLE gtest10 (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest10_pkey" for table "gtest10"
ALTER TABLE gtest10 DROP COLUMN b;
\d gtest10
Table "public.gtest10"
Column | Type | Modifiers
--------+---------+-----------
a | integer | not null
Indexes:
"gtest10_pkey" PRIMARY KEY, btree (a) TABLESPACE pg_default
CREATE TABLE gtest10a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest10a_pkey" for table "gtest10a"
ALTER TABLE gtest10a DROP COLUMN b;
INSERT INTO gtest10a (a) VALUES (1);
DROP TABLE gtest10a;
-- privileges
CREATE USER regress_user11 with password 'Gauss_123';
CREATE TABLE gtest11s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (b * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest11s_pkey" for table "gtest11s"
INSERT INTO gtest11s VALUES (1, 10), (2, 20);
GRANT SELECT (a, c) ON gtest11s TO regress_user11;
CREATE FUNCTION gf1(a int) RETURNS int AS $$ SELECT a * 3 $$ IMMUTABLE LANGUAGE SQL;
REVOKE ALL ON FUNCTION gf1(int) FROM PUBLIC;
CREATE TABLE gtest12s (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (gf1(b)) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest12s_pkey" for table "gtest12s"
INSERT INTO gtest12s VALUES (1, 10), (2, 20);
GRANT SELECT (a, c) ON gtest12s TO regress_user11;
SET ROLE regress_user11 PASSWORD 'Gauss_123';
SELECT a, b FROM gtest11s; -- not allowed
ERROR: permission denied for relation gtest11s
DETAIL: N/A
SELECT a, c FROM gtest11s; -- allowed
a | c
---+----
1 | 20
2 | 40
(2 rows)
SELECT gf1(10); -- not allowed
ERROR: permission denied for function gf1
DETAIL: N/A
CONTEXT: referenced column: gf1
SELECT a, c FROM gtest12s; -- allowed
a | c
---+----
1 | 30
2 | 60
(2 rows)
RESET ROLE;
DROP TABLE gtest11s, gtest12s;
DROP FUNCTION gf1(int);
DROP USER regress_user11;
-- check constraints
CREATE TABLE gtest20 (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED CHECK (b < 50));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest20_pkey" for table "gtest20"
INSERT INTO gtest20 (a) VALUES (10); -- ok
INSERT INTO gtest20 (a) VALUES (30); -- violates constraint
ERROR: new row for relation "gtest20" violates check constraint "gtest20_b_check"
DETAIL: N/A
CREATE TABLE gtest20a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest20a_pkey" for table "gtest20a"
INSERT INTO gtest20a (a) VALUES (10);
INSERT INTO gtest20a (a) VALUES (30);
ALTER TABLE gtest20a ADD CHECK (b < 50); -- fails on existing row
ERROR: check constraint "gtest20a_b_check" is violated by some row
CREATE TABLE gtest20b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest20b_pkey" for table "gtest20b"
INSERT INTO gtest20b (a) VALUES (10);
INSERT INTO gtest20b (a) VALUES (30);
ALTER TABLE gtest20b ADD CONSTRAINT chk CHECK (b < 50) NOT VALID;
ALTER TABLE gtest20b VALIDATE CONSTRAINT chk; -- fails on existing row
ERROR: check constraint "chk" is violated by some row
DROP TABLE gtest20a,gtest20b;
DROP TABLE gtest20;
-- not-null constraints
CREATE TABLE gtest21a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED NOT NULL);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest21a_pkey" for table "gtest21a"
INSERT INTO gtest21a (a) VALUES (1); -- ok
INSERT INTO gtest21a (a) VALUES (0); -- violates constraint
ERROR: null value in column "b" violates not-null constraint
DETAIL: Failing row contains (0, null).
CREATE TABLE gtest21b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (nullif(a, 0)) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest21b_pkey" for table "gtest21b"
ALTER TABLE gtest21b ALTER COLUMN b SET NOT NULL;
INSERT INTO gtest21b (a) VALUES (1); -- ok
INSERT INTO gtest21b (a) VALUES (0); -- violates constraint
ERROR: null value in column "b" violates not-null constraint
DETAIL: Failing row contains (0, null).
ALTER TABLE gtest21b ALTER COLUMN b DROP NOT NULL;
INSERT INTO gtest21b (a) VALUES (0); -- ok now
DROP TABLE gtest21a,gtest21b;
-- index constraints
CREATE TABLE gtest22a (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a / 2) STORED UNIQUE);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest22a_pkey" for table "gtest22a"
NOTICE: CREATE TABLE / UNIQUE will create implicit index "gtest22a_b_key" for table "gtest22a"
INSERT INTO gtest22a VALUES (2);
INSERT INTO gtest22a VALUES (3);
INSERT INTO gtest22a VALUES (4);
ERROR: duplicate key value violates unique constraint "gtest22a_b_key"
DETAIL: Key (b)=(2) already exists.
CREATE TABLE gtest22b (a int, b int GENERATED ALWAYS AS (a / 2) STORED, PRIMARY KEY (a, b));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest22b_pkey" for table "gtest22b"
INSERT INTO gtest22b VALUES (2);
INSERT INTO gtest22b VALUES (2);
ERROR: duplicate key value violates unique constraint "gtest22b_pkey"
DETAIL: Key (a, b)=(2, 1) already exists.
DROP TABLE gtest22b,gtest22a;
-- indexes
CREATE TABLE gtest22c (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
CREATE INDEX gtest22c_b_idx ON gtest22c (b);
CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3));
CREATE INDEX gtest22c_pred_idx ON gtest22c (a) WHERE b > 0;
\d gtest22c
Table "public.gtest22c"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer |
b | integer | generated always as ((a * 2)) stored
Indexes:
"gtest22c_b_idx" btree (b) TABLESPACE pg_default
"gtest22c_expr_idx" btree ((b * 3)) TABLESPACE pg_default
"gtest22c_pred_idx" btree (a) TABLESPACE pg_default WHERE b > 0
INSERT INTO gtest22c VALUES (1), (2), (3);
SET enable_seqscan TO off;
SET enable_bitmapscan TO off;
EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b = 4;
QUERY PLAN
---------------------------------------------
[Bypass]
Index Scan using gtest22c_b_idx on gtest22c
Index Cond: (b = 4)
(3 rows)
SELECT * FROM gtest22c WHERE b = 4;
a | b
---+---
2 | 4
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE b * 3 = 6;
QUERY PLAN
------------------------------------------------
[Bypass]
Index Scan using gtest22c_expr_idx on gtest22c
Index Cond: ((b * 3) = 6)
(3 rows)
SELECT * FROM gtest22c WHERE b * 3 = 6;
a | b
---+---
1 | 2
(1 row)
EXPLAIN (COSTS OFF) SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
QUERY PLAN
------------------------------------------------
[Bypass]
Index Scan using gtest22c_pred_idx on gtest22c
Index Cond: (a = 1)
(3 rows)
SELECT * FROM gtest22c WHERE a = 1 AND b > 0;
a | b
---+---
1 | 2
(1 row)
RESET enable_seqscan;
RESET enable_bitmapscan;
DROP TABLE gtest22c;
-- foreign keys
CREATE TABLE gtest23a (x int PRIMARY KEY, y int);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23a_pkey" for table "gtest23a"
INSERT INTO gtest23a VALUES (1, 11), (2, 22), (3, 33);
CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON UPDATE CASCADE); -- error
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23x_pkey" for table "gtest23x"
ERROR: invalid ON UPDATE action for foreign key constraint containing generated column
CREATE TABLE gtest23x (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x) ON DELETE SET NULL); -- error
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23x_pkey" for table "gtest23x"
ERROR: invalid ON DELETE action for foreign key constraint containing generated column
CREATE TABLE gtest23b (a int PRIMARY KEY, b int GENERATED ALWAYS AS (a * 2) STORED REFERENCES gtest23a (x));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23b_pkey" for table "gtest23b"
\d gtest23b
Table "public.gtest23b"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer | not null
b | integer | generated always as ((a * 2)) stored
Indexes:
"gtest23b_pkey" PRIMARY KEY, btree (a) TABLESPACE pg_default
Foreign-key constraints:
"gtest23b_b_fkey" FOREIGN KEY (b) REFERENCES gtest23a(x)
INSERT INTO gtest23b VALUES (1); -- ok
INSERT INTO gtest23b VALUES (5); -- error
ERROR: insert or update on table "gtest23b" violates foreign key constraint "gtest23b_b_fkey"
DETAIL: Key (b)=(10) is not present in table "gtest23a".
DROP TABLE gtest23b;
DROP TABLE gtest23a;
CREATE TABLE gtest23p (x int, y int GENERATED ALWAYS AS (x * 2) STORED, PRIMARY KEY (y));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23p_pkey" for table "gtest23p"
INSERT INTO gtest23p VALUES (1), (2), (3);
CREATE TABLE gtest23q (a int PRIMARY KEY, b int REFERENCES gtest23p (y));
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest23q_pkey" for table "gtest23q"
INSERT INTO gtest23q VALUES (1, 2); -- ok
INSERT INTO gtest23q VALUES (2, 5); -- error
ERROR: insert or update on table "gtest23q" violates foreign key constraint "gtest23q_b_fkey"
DETAIL: Key (b)=(5) is not present in table "gtest23p".
DROP TABLE gtest23q;
-- domains
CREATE DOMAIN gtestdomain1 AS int CHECK (VALUE < 10);
CREATE TABLE gtest24 (a int PRIMARY KEY, b gtestdomain1 GENERATED ALWAYS AS (a * 2) STORED);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest24_pkey" for table "gtest24"
INSERT INTO gtest24 (a) VALUES (4); -- ok
INSERT INTO gtest24 (a) VALUES (6); -- error
ERROR: value for domain gtestdomain1 violates check constraint "gtestdomain1_check"
DROP TABLE gtest24;
DROP DOMAIN gtestdomain1;
-- typed tables (currently not supported)
CREATE TYPE gtest_type AS (f1 integer, f2 text, f3 bigint);
CREATE TABLE gtest28 OF gtest_type (f1 WITH OPTIONS GENERATED ALWAYS AS (f2 *2) STORED);
ERROR: generated columns are not supported on typed tables
DROP TYPE gtest_type CASCADE;
-- partitioned table
CREATE TABLE gtest_parent (f1 date NOT NULL, f2 text, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f1) ( PARTITION p1 VALUES LESS THAN ('2016-07-16'));
INSERT INTO gtest_parent (f1, f2) VALUES ('2016-07-15', 1);
SELECT * FROM gtest_parent;
f1 | f2 | f3
--------------------------+----+----
Fri Jul 15 00:00:00 2016 | 1 | 2
(1 row)
DROP TABLE gtest_parent;
-- generated columns in partition key (not allowed)
CREATE TABLE gtest_parent (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 2) STORED) PARTITION BY RANGE (f3) ( PARTITION p1 VALUES LESS THAN ('2016-07-16'));
ERROR: cannot use generated column in partition key
DETAIL: Column "f3" is a generated column.
-- ALTER TABLE ... ADD COLUMN
CREATE TABLE gtest25 (a int PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest25_pkey" for table "gtest25"
INSERT INTO gtest25 VALUES (3), (4);
ALTER TABLE gtest25 ADD COLUMN b int GENERATED ALWAYS AS (a * 3) STORED;
SELECT * FROM gtest25 ORDER BY a;
a | b
---+----
3 | 9
4 | 12
(2 rows)
ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (b * 4) STORED; -- error
ERROR: cannot use generated column "b" in column generation expression
DETAIL: A generated column cannot reference another generated column.
ALTER TABLE gtest25 ADD COLUMN x int GENERATED ALWAYS AS (z * 4) STORED; -- error
ERROR: column "z" does not exist
DROP TABLE gtest25;
-- ALTER TABLE ... ALTER COLUMN
CREATE TABLE gtest27 (
a int,
b int GENERATED ALWAYS AS (a * 2) STORED
);
INSERT INTO gtest27 (a) VALUES (3), (4);
ALTER TABLE gtest27 ALTER COLUMN a TYPE text; -- error
ERROR: cannot alter type of a column used by a generated column
DETAIL: Column "a" is used by generated column "b".
ALTER TABLE gtest27 ALTER COLUMN b TYPE numeric;
\d gtest27
Table "public.gtest27"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer |
b | numeric | generated always as ((a * 2)) stored
SELECT * FROM gtest27;
a | b
---+---
3 | 6
4 | 8
(2 rows)
ALTER TABLE gtest27 ALTER COLUMN b TYPE boolean USING b <> 0;
ALTER TABLE gtest27 ALTER COLUMN b DROP DEFAULT; -- error
ERROR: column "b" of relation "gtest27" is a generated column
\d gtest27
Table "public.gtest27"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer |
b | boolean | generated always as ((a * 2)) stored
DROP TABLE gtest27;
-- triggers
CREATE TABLE gtest26 (
a int PRIMARY KEY,
b int GENERATED ALWAYS AS (a * 2) STORED
);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "gtest26_pkey" for table "gtest26"
CREATE FUNCTION gtest_trigger_func() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF tg_op IN ('DELETE', 'UPDATE') THEN
RAISE INFO '%: %: old = %', TG_NAME, TG_WHEN, OLD;
END IF;
IF tg_op IN ('INSERT', 'UPDATE') THEN
RAISE INFO '%: %: new = %', TG_NAME, TG_WHEN, NEW;
END IF;
IF tg_op = 'DELETE' THEN
RETURN OLD;
ELSE
RETURN NEW;
END IF;
END
$$;
CREATE TRIGGER gtest1 BEFORE DELETE OR UPDATE ON gtest26
FOR EACH ROW
WHEN (OLD.b < 0) -- ok
EXECUTE PROCEDURE gtest_trigger_func();
CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26
FOR EACH ROW
WHEN (NEW.b < 0) -- error
EXECUTE PROCEDURE gtest_trigger_func();
ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns
LINE 3: WHEN (NEW.b < 0)
^
DETAIL: Column "b" is a generated column.
CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26
FOR EACH ROW
WHEN (NEW.* IS NOT NULL) -- error
EXECUTE PROCEDURE gtest_trigger_func();
ERROR: BEFORE trigger's WHEN condition cannot reference NEW generated columns
LINE 3: WHEN (NEW.* IS NOT NULL)
^
DETAIL: A whole-row reference is used and the table contains generated columns.
CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26
FOR EACH ROW
WHEN (NEW.a < 0)
EXECUTE PROCEDURE gtest_trigger_func();
CREATE TRIGGER gtest3 AFTER DELETE OR UPDATE ON gtest26
FOR EACH ROW
WHEN (OLD.b < 0) -- ok
EXECUTE PROCEDURE gtest_trigger_func();
CREATE TRIGGER gtest4 AFTER INSERT OR UPDATE ON gtest26
FOR EACH ROW
WHEN (NEW.b < 0) -- ok
EXECUTE PROCEDURE gtest_trigger_func();
INSERT INTO gtest26 (a) VALUES (-2), (0), (3);
INFO: gtest2: BEFORE: new = (-2,)
INFO: gtest4: AFTER: new = (-2,-4)
SELECT * FROM gtest26 ORDER BY a;
a | b
----+----
-2 | -4
0 | 0
3 | 6
(3 rows)
UPDATE gtest26 SET a = a * -2;
INFO: gtest1: BEFORE: old = (-2,-4)
INFO: gtest1: BEFORE: new = (4,)
INFO: gtest3: AFTER: old = (-2,-4)
INFO: gtest3: AFTER: new = (4,8)
INFO: gtest4: AFTER: old = (3,6)
INFO: gtest4: AFTER: new = (-6,-12)
SELECT * FROM gtest26 ORDER BY a;
a | b
----+-----
-6 | -12
0 | 0
4 | 8
(3 rows)
DELETE FROM gtest26 WHERE a = -6;
INFO: gtest1: BEFORE: old = (-6,-12)
INFO: gtest3: AFTER: old = (-6,-12)
SELECT * FROM gtest26 ORDER BY a;
a | b
---+---
0 | 0
4 | 8
(2 rows)
DROP TRIGGER gtest1 ON gtest26;
DROP TRIGGER gtest2 ON gtest26;
DROP TRIGGER gtest3 ON gtest26;
-- Check that an UPDATE of "a" fires the trigger for UPDATE OF b, per
-- SQL standard.
CREATE FUNCTION gtest_trigger_func3() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
RAISE NOTICE 'OK';
RETURN NEW;
END
$$;
CREATE TRIGGER gtest11 BEFORE UPDATE OF b ON gtest26
FOR EACH ROW
EXECUTE PROCEDURE gtest_trigger_func3();
UPDATE gtest26 SET a = 1 WHERE a = 0;
NOTICE: OK
DROP TRIGGER gtest11 ON gtest26;
TRUNCATE gtest26;
-- check that modifications of stored generated columns in triggers do
-- not get propagated
CREATE FUNCTION gtest_trigger_func4() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
NEW.a = 10;
NEW.b = 300;
RETURN NEW;
END;
$$;
CREATE TRIGGER gtest12_01 BEFORE UPDATE ON gtest26
FOR EACH ROW
EXECUTE PROCEDURE gtest_trigger_func();
CREATE TRIGGER gtest12_02 BEFORE UPDATE ON gtest26
FOR EACH ROW
EXECUTE PROCEDURE gtest_trigger_func4();
CREATE TRIGGER gtest12_03 BEFORE UPDATE ON gtest26
FOR EACH ROW
EXECUTE PROCEDURE gtest_trigger_func();
INSERT INTO gtest26 (a) VALUES (1);
UPDATE gtest26 SET a = 11 WHERE a = 1;
INFO: gtest12_01: BEFORE: old = (1,2)
INFO: gtest12_01: BEFORE: new = (11,)
INFO: gtest12_03: BEFORE: old = (1,2)
INFO: gtest12_03: BEFORE: new = (10,)
SELECT * FROM gtest26 ORDER BY a;
a | b
----+----
10 | 20
(1 row)
DROP TABLE gtest26;
DROP FUNCTION gtest_trigger_func4;
DROP FUNCTION gtest_trigger_func3;
DROP FUNCTION gtest_trigger_func;
-- LIKE INCLUDING GENERATED and dropped column handling
CREATE TABLE gtest28a (
a int,
b int,
c int,
x int GENERATED ALWAYS AS (b * 2) STORED
);
ALTER TABLE gtest28a DROP COLUMN a;
CREATE TABLE gtest28b (LIKE gtest28a INCLUDING GENERATED);
\d gtest28*
Table "public.gtest28a"
Column | Type | Modifiers
--------+---------+--------------------------------------
b | integer |
c | integer |
x | integer | generated always as ((b * 2)) stored
Table "public.gtest28b"
Column | Type | Modifiers
--------+---------+--------------------------------------
b | integer |
c | integer |
x | integer | generated always as ((b * 2)) stored
DROP TABLE gtest28a;
DROP TABLE gtest28b;
CREATE TABLE test_like_gen_1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
\d test_like_gen_1
Table "public.test_like_gen_1"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer |
b | integer | generated always as ((a * 2)) stored
INSERT INTO test_like_gen_1 (a) VALUES (1);
SELECT * FROM test_like_gen_1;
a | b
---+---
1 | 2
(1 row)
CREATE TABLE test_like_gen_2 (LIKE test_like_gen_1);
\d test_like_gen_2
Table "public.test_like_gen_2"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | integer |
INSERT INTO test_like_gen_2 (a) VALUES (1);
SELECT * FROM test_like_gen_2;
a | b
---+---
1 |
(1 row)
CREATE TABLE test_like_gen_3 (LIKE test_like_gen_1 INCLUDING GENERATED);
\d test_like_gen_3
Table "public.test_like_gen_3"
Column | Type | Modifiers
--------+---------+--------------------------------------
a | integer |
b | integer | generated always as ((a * 2)) stored
INSERT INTO test_like_gen_3 (a) VALUES (1);
SELECT * FROM test_like_gen_3;
a | b
---+---
1 | 2
(1 row)
DROP TABLE test_like_gen_1, test_like_gen_2, test_like_gen_3;
-- function
CREATE TABLE t1(height_cm int,height_in int GENERATED ALWAYS AS (height_cm * 2) STORED);
CREATE OR REPLACE FUNCTION gen_test(a integer) RETURNS int as $$
declare
b int;
begin
DELETE t1 where height_cm = a;
INSERT INTO t1 values(a);
SELECT height_in INTO b FROM t1 where height_cm = a;
return b;
end;
$$ language plpgsql;
select gen_test(100);
gen_test
----------
200
(1 row)
drop function gen_test;
DROP TABLE t1;
-- sequence test
CREATE SEQUENCE seq1 START WITH 33;
-- error
CREATE TABLE t1 (id serial,id1 integer GENERATED ALWAYS AS (nextval('seq1')) STORED);
NOTICE: CREATE TABLE will create implicit sequence "t1_id_seq" for serial column "t1.id"
ERROR: generation expression is not immutable
DROP SEQUENCE seq1;
--merage test
CREATE TABLE products_base
(
product_id INTEGER DEFAULT 0,
product_name VARCHAR(60) DEFAULT 'null',
category VARCHAR(60) DEFAULT 'unknown',
total INTEGER DEFAULT '0'
);
INSERT INTO products_base VALUES (1501, 'vivitar 35mm', 'electrncs', 100);
INSERT INTO products_base VALUES (1502, 'olympus is50', 'electrncs', 100);
INSERT INTO products_base VALUES (1600, 'play gym', 'toys', 100);
INSERT INTO products_base VALUES (1601, 'lamaze', 'toys', 100);
INSERT INTO products_base VALUES (1666, 'harry potter', 'dvd', 100);
CREATE TABLE newproducts_base
(
product_id INTEGER DEFAULT 0,
product_name VARCHAR(60) DEFAULT 'null',
category VARCHAR(60) DEFAULT 'unknown',
total INTEGER DEFAULT '0'
);
INSERT INTO newproducts_base VALUES (1502, 'olympus camera', 'electrncs', 200);
INSERT INTO newproducts_base VALUES (1601, 'lamaze', 'toys', 200);
INSERT INTO newproducts_base VALUES (1666, 'harry potter', 'toys', 200);
INSERT INTO newproducts_base VALUES (1700, 'wait interface', 'books', 200);
CREATE TABLE products_row
(
product_id INTEGER DEFAULT 0,
product_name VARCHAR(60) DEFAULT 'null',
category VARCHAR(60) DEFAULT 'unknown',
total INTEGER DEFAULT '0',
height_in int GENERATED ALWAYS AS (total * 2) STORED
);
INSERT INTO products_row SELECT * FROM products_base;
CREATE TABLE newproducts_row
(
product_id INTEGER DEFAULT 0,
product_name VARCHAR(60) DEFAULT 'null',
category VARCHAR(60) DEFAULT 'unknown',
total INTEGER DEFAULT '0',
height_in int GENERATED ALWAYS AS (total * 3) STORED
);
INSERT INTO newproducts_row SELECT * FROM newproducts_base;
MERGE INTO products_row p
USING newproducts_row np
ON p.product_id = np.product_id
WHEN MATCHED THEN
UPDATE SET product_name = np.product_name, category = np.category, total = np.total
WHEN NOT MATCHED THEN
INSERT VALUES (np.product_id, np.product_name, np.category, np.total);
SELECT * FROM products_row;
product_id | product_name | category | total | height_in
------------+----------------+-----------+-------+-----------
1501 | vivitar 35mm | electrncs | 100 | 200
1600 | play gym | toys | 100 | 200
1502 | olympus camera | electrncs | 200 | 400
1601 | lamaze | toys | 200 | 400
1666 | harry potter | toys | 200 | 400
1700 | wait interface | books | 200 | 400
(6 rows)
CREATE TABLE hw_create_as_test2(C_INT) as SELECT height_in FROM newproducts_row;
SELECT * FROM hw_create_as_test2;
c_int
-------
600
600
600
600
(4 rows)
DROP TABLE hw_create_as_test2;
DROP TABLE products_row;
DROP TABLE newproducts_row;
DROP TABLE newproducts_base;
DROP TABLE products_base;
--bypass test
INSERT INTO gtest1 values (200);
SELECT * FROM gtest1;
a | b
-----+-----
1 | 2
2 | 4
3 | 6
4 | 8
200 | 400
(5 rows)
UPDATE gtest1 set a = 300 where a = 200;
SELECT * FROM gtest1;
a | b
-----+-----
1 | 2
2 | 4
3 | 6
4 | 8
300 | 600
(5 rows)
--null test
CREATE TABLE t1 (id int,id1 integer GENERATED ALWAYS AS (id*2) STORED);
INSERT INTO t1 values(100);
SELECT * FROM t1;
id | id1
-----+-----
100 | 200
(1 row)
UPDATE t1 set id = 200;
SELECT * FROM t1;
id | id1
-----+-----
200 | 400
(1 row)
UPDATE t1 set id = NULL;
SELECT * FROM t1;
id | id1
----+-----
|
(1 row)
DROP TABLE t1;
--cstore not support
CREATE TABLE t2(height_cm int,height_in int GENERATED ALWAYS AS (height_cm * 2) STORED) WITH (ORIENTATION = COLUMN);
ERROR: column/timeseries store unsupport constraint "GENERATED COL"
--ustore engine test
CREATE TABLE ustoretest (a int PRIMARY KEY, b int, c int GENERATED ALWAYS AS (a * 2) STORED) WITH (STORAGE_TYPE = USTORE, init_td=32);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "ustoretest_pkey" for table "ustoretest"
INSERT INTO ustoretest(a,b) values(2,3),(4,5);
SELECT * FROM ustoretest;
a | b | c
---+---+---
2 | 3 | 4
4 | 5 | 8
(2 rows)
UPDATE ustoretest SET a=7 WHERE a=2;
SELECT * FROM ustoretest;
a | b | c
---+---+----
7 | 3 | 14
4 | 5 | 8
(2 rows)
DROP TABLE ustoretest;
DROP TABLE gtest0;
DROP TABLE gtest1;
DROP TABLE gtest2;
DROP TABLE gtest3;
DROP TABLE gtest10;