Re: BUG #16675: VALUES not working for CITEXT

From: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
To: mcowne(at)webroot(dot)com, PostgreSQL mailing lists <pgsql-bugs(at)lists(dot)postgresql(dot)org>
Subject: Re: BUG #16675: VALUES not working for CITEXT
Date: 2020-10-16 11:20:17
Message-ID: CAFj8pRBd9Lrb9x_jgb9SF_qnYaYq4-fJTvuqD3KDOMdxSb+Y0g@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

pá 16. 10. 2020 v 13:01 odesílatel PG Bug reporting form <
noreply(at)postgresql(dot)org> napsal:

> The following bug has been logged on the website:
>
> Bug reference: 16675
> Logged by: Mark Cowne
> Email address: mcowne(at)webroot(dot)com
> PostgreSQL version: 11.7
> Operating system: x86_64-pc-linux-gnu
> Description:
>
> -- Fourth SELECT doesn't return anything and should.
>
> CREATE TABLE Test(Col CITEXT NOT NULL PRIMARY KEY);
>
> INSERT INTO Test(Col) VALUES('ABC');
>
> SELECT Col FROM Test WHERE Col IN ('abc');
> SELECT Col FROM Test WHERE Col IN ('ABC');
> SELECT Col FROM Test WHERE Col IN (VALUES('ABC'));
> SELECT Col FROM Test WHERE Col IN (VALUES('abc'));
>

This is not a bug - it is a feature and an effect of some others features.

Usual literal constant in Postgres has an "unknown" type. Real type is
derived from context.

postgres=# select citext 'ABC' = 'abc';
┌──────────┐
│ ?column? │
╞══════════╡
│ t │
└──────────┘
(1 row)

so there is comparison of citext <-> unknown ==> citext <-> citext

but VALUES klause force unknown to text type.

postgres=# select citext 'ABC' = text 'abc';
┌──────────┐
│ ?column? │
╞══════════╡
│ f │
└──────────┘
(1 row)

"text" type is marked as prefered - so if there are more possibilities and
one is type "text", then this type is selected without raising an error.

postgres=# explain verbose SELECT Col FROM Test WHERE Col IN ('abc');
┌───────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN

╞═══════════════════════════════════════════════════════════════════════════════════╡
│ Index Only Scan using test_pkey on public.test (cost=0.15..8.17 rows=1
width=32) │
│ Output: col

│ Index Cond: (test.col = 'abc'::citext)

└───────────────────────────────────────────────────────────────────────────────────┘
(3 rows)

postgres=# explain verbose SELECT Col FROM Test WHERE Col IN
(VALUES('abc'));
┌─────────────────────────────────────────────────────────────┐
│ QUERY PLAN │
╞═════════════════════════════════════════════════════════════╡
│ Seq Scan on public.test (cost=0.00..27.00 rows=1 width=32) │
│ Output: test.col │
│ Filter: ((test.col)::text = 'abc'::text) │
└─────────────────────────────────────────────────────────────┘
(3 rows)

if you want force cast to citext type, you should to use explicit cast
inside VALUES clause

postgres=# explain verbose SELECT Col FROM Test WHERE Col IN
(VALUES('abc'::citext));
┌───────────────────────────────────────────────────────────────────────────────────┐
│ QUERY PLAN

╞═══════════════════════════════════════════════════════════════════════════════════╡
│ Index Only Scan using test_pkey on public.test (cost=0.15..8.17 rows=1
width=32) │
│ Output: test.col

│ Index Cond: (test.col = 'abc'::citext)

└───────────────────────────────────────────────────────────────────────────────────┘
(3 rows)

postgres=# SELECT Col FROM Test WHERE Col IN (VALUES('abc'::citext));
┌─────┐
│ col │
╞═════╡
│ ABC │
└─────┘
(1 row)

Regards

Pavel

> DROP TABLE Test;
>
>

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message David G. Johnston 2020-10-16 14:23:27 Re: BUG #16674: The idle connection get created automatically
Previous Message PG Bug reporting form 2020-10-16 10:10:21 BUG #16675: VALUES not working for CITEXT