Re: Primary key data type: integer vs identity - Mailing list pgsql-general
From | Ken Tanzer |
---|---|
Subject | Re: Primary key data type: integer vs identity |
Date | |
Msg-id | CAD3a31WTVBL7o41FpqQB-jAiBgSyf+NVt7Oc5zmpJ7rBFZA9=w@mail.gmail.com Whole thread Raw |
In response to | Re: Primary key data type: integer vs identity (Adrian Klaver <adrian.klaver@aklaver.com>) |
Responses |
Re: Primary key data type: integer vs identity
|
List | pgsql-general |
On Fri, Apr 19, 2019 at 1:39 PM Adrian Klaver <adrian.klaver@aklaver.com> wrote:
On 4/19/19 1:02 PM, Ken Tanzer wrote:
> On Fri, Apr 19, 2019 at 12:50 PM Adrian Klaver
> <adrian.klaver@aklaver.com <mailto:adrian.klaver@aklaver.com>> wrote:
>
> On 4/19/19 12:35 PM, Ken Tanzer wrote:
>
> >
> > Thanks Adrian. You are as usual correct. (I had a bunch of tables
> > created by a function that I assumed were serial, but were not.)
> > Identity columns still seem tidier and more manageable. Can you
> tell if
> > the function I referenced would change the ownership or not?
>
> I believe in 'when it doubt try it, whats the worst that can happen?:)':
>
>
> I agree, and if I had a copy of 10+ running, I probably would have! :)
>
> <NOTE> I needed to be a superuser to run due to this:
> ERROR: permission denied for table pg_depend
> CONTEXT: SQL statement "UPDATE pg_depend
> SET deptype = 'i'
> WHERE (classid, objid, objsubid) = ('pg_class'::regclass,
> seqid, 0)
> AND deptype = 'a'"
> PL/pgSQL function upgrade_serial_to_identity(regclass,name) line 31 at
> SQL statement
>
>
> test=# create table serial_test(id serial, fld_1 text);
> CREATE TABLE
> test=# \dp serial_test
> Access privileges
> Schema | Name | Type | Access privileges | Column
> privileges |
> Policies
> --------+-------------+-------+-------------------+-------------------+----------
> public | serial_test | table | |
> |
> (1 row)
>
> test=# select upgrade_serial_to_identity('serial_test', 'id');
> upgrade_serial_to_identity
> ----------------------------
>
> (1 row)
>
> test=# \d serial_test
> Table "public.serial_test"
> Column | Type | Collation | Nullable | Default
>
> --------+---------+-----------+----------+----------------------------------
> id | integer | | not null | generated by default as
> identity
> fld_1 | text | | |
>
>
> test=# \dp+ serial_test
> Access privileges
> Schema | Name | Type | Access privileges | Column
> privileges |
> Policies
> --------+-------------+-------+-------------------+-------------------+----------
> public | serial_test | table | |
> |
> (1 row)
>
>
> Maybe I'm missing it, but I'm not really sure what that is supposed to
> be telling me about the ownership of the sequence.
>
> The scenario I'm wondering about is:
>
> Table A owned by User 1, and has column created as serial
> The created sequence is altered to be owned by User 2 (with User 1
> granted select & update)
> upgrade_serial_to_identity applied to Table A
> At that point, who owns the sequence?
>
> I can wait until I've got 10+ running and try it myself, but I thought
> maybe someone would know the answer and be willing to share.
select version();
version
----------------------------------------------------------------------------------------------------------------------------
PostgreSQL 11.2 on x86_64-pc-linux-gnu, compiled by gcc (SUSE Linux)
7.3.1 20180323 [gcc-7-branch revision 258812], 64-bit
select session_user, current_user;
session_user | current_user
--------------+--------------
aklaver | aklaver
create table serial_test(id serial, fld_1 text);
CREATE TABLE
\d
List of relations
Schema | Name | Type | Owner
--------+--------------------+----------+----------
public | serial_test | table | aklaver
public | serial_test_id_seq | sequence | aklaver
test_(aklaver)> \c - postgres
You are now connected to database "test" as user "postgres".
test_(postgres)# select session_user, current_user;
session_user | current_user
--------------+--------------
postgres | postgres
(1 row)
test_(postgres)# select upgrade_serial_to_identity('serial_test', 'id');
upgrade_serial_to_identity
----------------------------
(1 row)
List of relations
Schema | Name | Type | Owner
--------+--------------------+----------+----------
public | serial_test | table | aklaver
public | serial_test_id_seq | sequence | aklaver
The function is working directly on the system catalogs and I do not
anything that changes ownership:
UPDATE pg_depend
SET deptype = 'i'
WHERE (classid, objid, objsubid) = ('pg_class'::regclass, seqid, 0)
AND deptype = 'a';
-- mark the column as identity column
UPDATE pg_attribute
SET attidentity = 'd'
WHERE attrelid = tbl
AND attname = col;
Thanks, though I don't see what this shows, since there were not separate users involved. So I loaded up a copy of 11.2, and discovered that you actually can't change the ownership of a sequence created by serial.
ag_tz_test=# ALTER SEQUENCE t_serial_id_seq OWNER TO develop;
ERROR: cannot change owner of sequence "t_serial_id_seq"
DETAIL: Sequence "t_serial_id_seq" is linked to table "t_serial".
I also missed the part in the article where it talks about assigning ownership to the column. In psql, it's easy to miss because a \ds (or \ds+) (as opposed to a \d) shows the user that owns the sequence, not a column:
test=# \ds+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+-------------------+----------+-------+------------+-------------
public | t_serial_id_seq | sequence | u1 | 8192 bytes |
Whereas if you look at \d it shows the column:
test=# \d+ t_serial_id_seq
Sequence "public.t_serial_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
---------+-------+---------+------------+-----------+---------+-------
integer | 1 | 1 | 2147483647 | 1 | no | 1
Owned by: public.t_serial.id
(Side note: it is surprising that the Size and Description don't show up with \d+. I always thought that a \d+ was the best way to get all the detail on an object.)
But even if you drop the default on the column, it doesn't seem like you can change the sequence's owner:
test=# ALTER TABLE t_serial ALTER COLUMN id DROP DEFAULT;
ALTER TABLE
test=# alter sequence t_serial_id_seq OWNER TO u2;
ERROR: cannot change owner of sequence "t_serial_id_seq"
DETAIL: Sequence "t_serial_id_seq" is linked to table "t_serial".
Although you can drop it:
DROP SEQUENCE t_serial_id_seq;
DROP SEQUENCE
Anyhoo, I've learned a bit more today, and thanks for your help!
Cheers,
Ken
AGENCY Software
A Free Software data system
By and for non-profits
(253) 245-3801
learn more about AGENCY or
follow the discussion.
pgsql-general by date: