From: | "[Quipsy] Markus Karg" <karg(at)quipsy(dot)de> |
---|---|
To: | "pgsql-general(at)lists(dot)postgresql(dot)org" <pgsql-general(at)lists(dot)postgresql(dot)org> |
Subject: | AW: Cast INTEGER to BIT confusion |
Date: | 2023-08-15 11:59:08 |
Message-ID: | dc7d35dc671e4b8196743a357356e707@quipsy.de |
Views: | Whole Thread | Raw Message | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
Thank you, Erik! Prefixing the search path in fact looks very interesting, and I think in this particular application it is a safe (and the only) solution.
Is setting the search path something that has to be done for each new connection / each user, or is this something static and global for the database?
Thanks a lot!
-Markus
-----Ursprüngliche Nachricht-----
Von: Erik Wienhold <ewie(at)ewie(dot)name>
Gesendet: Dienstag, 15. August 2023 13:48
An: [Quipsy] Markus Karg <karg(at)quipsy(dot)de>; pgsql-general(at)lists(dot)postgresql(dot)org
Betreff: Re: Cast INTEGER to BIT confusion
> On 15/08/2023 10:49 CEST [Quipsy] Markus Karg <karg(at)quipsy(dot)de> wrote:
>
> Hello PostgreSQL Community,
>
> I like to store just a single bit but that can be either 1 or 0, so I
> tried to do this:
>
> CREATE TABLE T (c BIT);
> INSERT INTO T VALUES (1);
> -- I MUST NOT change both lines in any way as these are part of a third-party application!
>
> Unfortunately this tells me:
>
> column "c" is of type bit but expression is of type integer
>
> So I logged in as a cluster admin and I tried this:
>
> CREATE CAST (integer AS bit) WITH INOUT AS IMPLICIT;
>
> Unfortunately that tells me:
>
> cast from type integer to type bit already exists
>
> This is confusing! Apparently PostgreSQL 15.3 comes with the needed
> cast out-of-the-box but it does not apply it? This is confusing!
>
> What is my fault?
The built-in cast is explicit (castcontext = 'e'):
=# SELECT * FROM pg_cast WHERE castsource = 'int'::regtype AND casttarget = 'bit'::regtype;
oid | castsource | casttarget | castfunc | castcontext | castmethod
-------+------------+------------+----------+-------------+------------
10186 | 23 | 1560 | 1683 | e | f
(1 row)
It's not possible to drop that cast and replace it with a custom one:
=# DROP CAST (int AS bit);
ERROR: cannot drop cast from integer to bit because it is required by the database system
You could create a custom domain if you're only interested in values 0 and 1 and don't use bit string functions. The search path must be changed so that domain bit overrides pg_catalog.bit:
=# CREATE SCHEMA xxx;
=# CREATE DOMAIN xxx.bit AS int;
=# SET search_path = xxx, pg_catalog;
=# CREATE TABLE t (c bit);
=# INSERT INTO t VALUES (1);
INSERT 0 1
But I would do that only if the third-party code cannot be tweaked because the custom domain could be confusing. It's also prone to errors as it relies on a specific search path order. Also make sure that regular users cannot create objects in schema xxx that would override objects in pg_catalog.
--
Erik
From | Date | Subject | |
---|---|---|---|
Next Message | [Quipsy] Markus Karg | 2023-08-15 12:02:21 | AW: Cast INTEGER to BIT confusion |
Previous Message | Erik Wienhold | 2023-08-15 11:48:16 | Re: Cast INTEGER to BIT confusion |