Fix CREATE TABLE / LIKE with bigint identity column
CREATE TABLE / LIKE with a bigint identity column would fail on platforms where long is 32 bits. Copying the sequence values used makeInteger(), which would truncate the 64-bit sequence data to 32 bits. To fix, use makeFloat() instead, like the parser. (This does not actually make use of floats, but stores the values as strings.) Bug: #15096 Reviewed-by: Michael Paquier <michael@paquier.xyz>
This commit is contained in:
parent
1f8a3327a9
commit
377b5ac484
@ -1752,12 +1752,19 @@ sequence_options(Oid relid)
|
|||||||
elog(ERROR, "cache lookup failed for sequence %u", relid);
|
elog(ERROR, "cache lookup failed for sequence %u", relid);
|
||||||
pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
|
pgsform = (Form_pg_sequence) GETSTRUCT(pgstuple);
|
||||||
|
|
||||||
options = lappend(options, makeDefElem("cache", (Node *) makeInteger(pgsform->seqcache), -1));
|
/* Use makeFloat() for 64-bit integers, like gram.y does. */
|
||||||
options = lappend(options, makeDefElem("cycle", (Node *) makeInteger(pgsform->seqcycle), -1));
|
options = lappend(options,
|
||||||
options = lappend(options, makeDefElem("increment", (Node *) makeInteger(pgsform->seqincrement), -1));
|
makeDefElem("cache", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqcache)), -1));
|
||||||
options = lappend(options, makeDefElem("maxvalue", (Node *) makeInteger(pgsform->seqmax), -1));
|
options = lappend(options,
|
||||||
options = lappend(options, makeDefElem("minvalue", (Node *) makeInteger(pgsform->seqmin), -1));
|
makeDefElem("cycle", (Node *) makeInteger(pgsform->seqcycle), -1));
|
||||||
options = lappend(options, makeDefElem("start", (Node *) makeInteger(pgsform->seqstart), -1));
|
options = lappend(options,
|
||||||
|
makeDefElem("increment", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqincrement)), -1));
|
||||||
|
options = lappend(options,
|
||||||
|
makeDefElem("maxvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmax)), -1));
|
||||||
|
options = lappend(options,
|
||||||
|
makeDefElem("minvalue", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqmin)), -1));
|
||||||
|
options = lappend(options,
|
||||||
|
makeDefElem("start", (Node *) makeFloat(psprintf(INT64_FORMAT, pgsform->seqstart)), -1));
|
||||||
|
|
||||||
ReleaseSysCache(pgstuple);
|
ReleaseSysCache(pgstuple);
|
||||||
|
|
||||||
|
@ -66,13 +66,13 @@ SELECT * FROM inhg; /* Two records with three columns in order x=x, xx=text, y=y
|
|||||||
(2 rows)
|
(2 rows)
|
||||||
|
|
||||||
DROP TABLE inhg;
|
DROP TABLE inhg;
|
||||||
CREATE TABLE test_like_id_1 (a int GENERATED ALWAYS AS IDENTITY, b text);
|
CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text);
|
||||||
\d test_like_id_1
|
\d test_like_id_1
|
||||||
Table "public.test_like_id_1"
|
Table "public.test_like_id_1"
|
||||||
Column | Type | Collation | Nullable | Default
|
Column | Type | Collation | Nullable | Default
|
||||||
--------+---------+-----------+----------+------------------------------
|
--------+--------+-----------+----------+------------------------------
|
||||||
a | integer | | not null | generated always as identity
|
a | bigint | | not null | generated always as identity
|
||||||
b | text | | |
|
b | text | | |
|
||||||
|
|
||||||
INSERT INTO test_like_id_1 (b) VALUES ('b1');
|
INSERT INTO test_like_id_1 (b) VALUES ('b1');
|
||||||
SELECT * FROM test_like_id_1;
|
SELECT * FROM test_like_id_1;
|
||||||
@ -83,11 +83,11 @@ SELECT * FROM test_like_id_1;
|
|||||||
|
|
||||||
CREATE TABLE test_like_id_2 (LIKE test_like_id_1);
|
CREATE TABLE test_like_id_2 (LIKE test_like_id_1);
|
||||||
\d test_like_id_2
|
\d test_like_id_2
|
||||||
Table "public.test_like_id_2"
|
Table "public.test_like_id_2"
|
||||||
Column | Type | Collation | Nullable | Default
|
Column | Type | Collation | Nullable | Default
|
||||||
--------+---------+-----------+----------+---------
|
--------+--------+-----------+----------+---------
|
||||||
a | integer | | not null |
|
a | bigint | | not null |
|
||||||
b | text | | |
|
b | text | | |
|
||||||
|
|
||||||
INSERT INTO test_like_id_2 (b) VALUES ('b2');
|
INSERT INTO test_like_id_2 (b) VALUES ('b2');
|
||||||
ERROR: null value in column "a" violates not-null constraint
|
ERROR: null value in column "a" violates not-null constraint
|
||||||
@ -100,10 +100,10 @@ SELECT * FROM test_like_id_2; -- identity was not copied
|
|||||||
CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY);
|
CREATE TABLE test_like_id_3 (LIKE test_like_id_1 INCLUDING IDENTITY);
|
||||||
\d test_like_id_3
|
\d test_like_id_3
|
||||||
Table "public.test_like_id_3"
|
Table "public.test_like_id_3"
|
||||||
Column | Type | Collation | Nullable | Default
|
Column | Type | Collation | Nullable | Default
|
||||||
--------+---------+-----------+----------+------------------------------
|
--------+--------+-----------+----------+------------------------------
|
||||||
a | integer | | not null | generated always as identity
|
a | bigint | | not null | generated always as identity
|
||||||
b | text | | |
|
b | text | | |
|
||||||
|
|
||||||
INSERT INTO test_like_id_3 (b) VALUES ('b3');
|
INSERT INTO test_like_id_3 (b) VALUES ('b3');
|
||||||
SELECT * FROM test_like_id_3; -- identity was copied and applied
|
SELECT * FROM test_like_id_3; -- identity was copied and applied
|
||||||
|
@ -37,7 +37,7 @@ INSERT INTO inhg VALUES ('x', 'foo', 'y'); /* fails due to constraint */
|
|||||||
SELECT * FROM inhg; /* Two records with three columns in order x=x, xx=text, y=y */
|
SELECT * FROM inhg; /* Two records with three columns in order x=x, xx=text, y=y */
|
||||||
DROP TABLE inhg;
|
DROP TABLE inhg;
|
||||||
|
|
||||||
CREATE TABLE test_like_id_1 (a int GENERATED ALWAYS AS IDENTITY, b text);
|
CREATE TABLE test_like_id_1 (a bigint GENERATED ALWAYS AS IDENTITY, b text);
|
||||||
\d test_like_id_1
|
\d test_like_id_1
|
||||||
INSERT INTO test_like_id_1 (b) VALUES ('b1');
|
INSERT INTO test_like_id_1 (b) VALUES ('b1');
|
||||||
SELECT * FROM test_like_id_1;
|
SELECT * FROM test_like_id_1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user