identity-cols.patch
text/x-patch
Filename: identity-cols.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/create_table.sgml | 13 | 3 |
| doc/src/sgml/ref/insert.sgml | 12 | 6 |
| src/backend/rewrite/rewriteHandler.c | 4 | 2 |
| src/test/regress/expected/identity.out | 17 | 11 |
| src/test/regress/sql/identity.sql | 4 | 2 |
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
new file mode 100644
index 22dbc07..b48a29e
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -803,8 +803,8 @@ WITH ( MODULUS <replaceable class="param
<para>
This clause creates the column as an <firstterm>identity
column</firstterm>. It will have an implicit sequence attached to it
- and the column in new rows will automatically have values from the
- sequence assigned to it.
+ and new rows in the column will automatically have values from the
+ sequence assigned to them.
</para>
<para>
@@ -815,12 +815,22 @@ WITH ( MODULUS <replaceable class="param
only accepted if the <command>INSERT</command> statement
specifies <literal>OVERRIDING SYSTEM VALUE</literal>. If <literal>BY
DEFAULT</literal> is specified, then the user-specified value takes
- precedence. See <xref linkend="sql-insert"/> for details. (In
+ precedence, unless the <command>INSERT</command> statement specifies
+ <literal>OVERRIDING USER VALUE</literal>.
+ See <xref linkend="sql-insert"/> for details. (In
the <command>COPY</command> command, user-specified values are always
used regardless of this setting.)
</para>
<para>
+ Additionally, if <literal>ALWAYS</literal> is specified, any attempt to
+ update the value of the column using an <command>UPDATE</command>
+ statement specifying any value other than <literal>DEFAULT</literal>
+ will be rejected. If <literal>BY DEFAULT</literal> is specified, the
+ system will allow values in the column to be updated.
+ </para>
+
+ <para>
The optional <replaceable>sequence_options</replaceable> clause can be
used to override the options of the sequence.
See <xref linkend="sql-createsequence"/> for details.
diff --git a/doc/src/sgml/ref/insert.sgml b/doc/src/sgml/ref/insert.sgml
new file mode 100644
index 62e142f..8108f31
--- a/doc/src/sgml/ref/insert.sgml
+++ b/doc/src/sgml/ref/insert.sgml
@@ -206,10 +206,16 @@ INSERT INTO <replaceable class="paramete
<term><literal>OVERRIDING SYSTEM VALUE</literal></term>
<listitem>
<para>
- Without this clause, it is an error to specify an explicit value
- (other than <literal>DEFAULT</literal>) for an identity column defined
- as <literal>GENERATED ALWAYS</literal>. This clause overrides that
- restriction.
+ If this clause is specified, then any values supplied for identity
+ columns will override the default sequence-generated values.
+ </para>
+
+ <para>
+ For an identity column defined as <literal>GENERATED ALWAYS</literal>,
+ it is an error to insert an explicit value (other than
+ <literal>DEFAULT</literal>) without specifying either
+ <literal>OVERRIDING SYSTEM VALUE</literal> or
+ <literal>OVERRIDING USER VALUE</literal>.
</para>
</listitem>
</varlistentry>
@@ -219,8 +225,8 @@ INSERT INTO <replaceable class="paramete
<listitem>
<para>
If this clause is specified, then any values supplied for identity
- columns defined as <literal>GENERATED BY DEFAULT</literal> are ignored
- and the default sequence-generated values are applied.
+ columns are ignored and the default sequence-generated values are
+ applied.
</para>
<para>
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
new file mode 100644
index 7eb41ff..3dc27eb
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -821,13 +821,15 @@ rewriteTargetListIU(List *targetList,
{
if (att_tup->attidentity == ATTRIBUTE_IDENTITY_ALWAYS && !apply_default)
{
- if (override != OVERRIDING_SYSTEM_VALUE)
+ if (override == OVERRIDING_USER_VALUE)
+ apply_default = true;
+ else if (override != OVERRIDING_SYSTEM_VALUE)
ereport(ERROR,
(errcode(ERRCODE_GENERATED_ALWAYS),
errmsg("cannot insert into column \"%s\"", NameStr(att_tup->attname)),
errdetail("Column \"%s\" is an identity column defined as GENERATED ALWAYS.",
NameStr(att_tup->attname)),
- errhint("Use OVERRIDING SYSTEM VALUE to override.")));
+ errhint("You must specify either OVERRIDING SYSTEM VALUE or OVERRIDING USER VALUE.")));
}
if (att_tup->attidentity == ATTRIBUTE_IDENTITY_BY_DEFAULT && override == OVERRIDING_USER_VALUE)
diff --git a/src/test/regress/expected/identity.out b/src/test/regress/expected/identity.out
new file mode 100644
index d7d5178..81044b2
--- a/src/test/regress/expected/identity.out
+++ b/src/test/regress/expected/identity.out
@@ -119,28 +119,32 @@ SELECT * FROM itest3;
-- OVERRIDING tests
INSERT INTO itest1 VALUES (10, 'xyz');
-INSERT INTO itest1 OVERRIDING USER VALUE VALUES (10, 'xyz');
+INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
+INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz');
SELECT * FROM itest1;
a | b
----+-----
1 |
2 |
10 | xyz
+ 20 | xyz
3 | xyz
-(4 rows)
+(5 rows)
INSERT INTO itest2 VALUES (10, 'xyz');
ERROR: cannot insert into column "a"
DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
-HINT: Use OVERRIDING SYSTEM VALUE to override.
-INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (10, 'xyz');
+HINT: You must specify either OVERRIDING SYSTEM VALUE or OVERRIDING USER VALUE.
+INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
+INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz');
SELECT * FROM itest2;
a | b
----+-----
1 |
2 |
- 10 | xyz
-(3 rows)
+ 20 | xyz
+ 3 | xyz
+(4 rows)
-- UPDATE tests
UPDATE itest1 SET a = 101 WHERE a = 1;
@@ -149,10 +153,11 @@ SELECT * FROM itest1;
a | b
-----+-----
10 | xyz
+ 20 | xyz
3 | xyz
101 |
4 |
-(4 rows)
+(5 rows)
UPDATE itest2 SET a = 101 WHERE a = 1;
ERROR: column "a" can only be updated to DEFAULT
@@ -162,9 +167,10 @@ SELECT * FROM itest2;
a | b
----+-----
1 |
- 10 | xyz
- 3 |
-(3 rows)
+ 20 | xyz
+ 3 | xyz
+ 4 |
+(4 rows)
-- COPY tests
CREATE TABLE itest9 (a int GENERATED ALWAYS AS IDENTITY, b text, c bigint);
@@ -240,7 +246,7 @@ SELECT * FROM itestv10;
INSERT INTO itestv11 VALUES (10, 'xyz');
ERROR: cannot insert into column "a"
DETAIL: Column "a" is an identity column defined as GENERATED ALWAYS.
-HINT: Use OVERRIDING SYSTEM VALUE to override.
+HINT: You must specify either OVERRIDING SYSTEM VALUE or OVERRIDING USER VALUE.
INSERT INTO itestv11 OVERRIDING SYSTEM VALUE VALUES (11, 'xyz');
SELECT * FROM itestv11;
a | b
diff --git a/src/test/regress/sql/identity.sql b/src/test/regress/sql/identity.sql
new file mode 100644
index a35f331..f74353f
--- a/src/test/regress/sql/identity.sql
+++ b/src/test/regress/sql/identity.sql
@@ -65,12 +65,14 @@ SELECT * FROM itest3;
-- OVERRIDING tests
INSERT INTO itest1 VALUES (10, 'xyz');
-INSERT INTO itest1 OVERRIDING USER VALUE VALUES (10, 'xyz');
+INSERT INTO itest1 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
+INSERT INTO itest1 OVERRIDING USER VALUE VALUES (30, 'xyz');
SELECT * FROM itest1;
INSERT INTO itest2 VALUES (10, 'xyz');
-INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (10, 'xyz');
+INSERT INTO itest2 OVERRIDING SYSTEM VALUE VALUES (20, 'xyz');
+INSERT INTO itest2 OVERRIDING USER VALUE VALUES (30, 'xyz');
SELECT * FROM itest2;