Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZAQH-00GqhL-Fy for pgsql-bugs@arkaria.postgresql.org; Wed, 31 Jul 2024 14:35:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sZAQF-008Ccn-R0 for pgsql-bugs@arkaria.postgresql.org; Wed, 31 Jul 2024 14:35:23 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZAQF-008CaU-Hl for pgsql-bugs@lists.postgresql.org; Wed, 31 Jul 2024 14:35:23 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sZAQ9-002S0A-Qh for pgsql-bugs@lists.postgresql.org; Wed, 31 Jul 2024 14:35:22 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 46VEZ6Jw3378621; Wed, 31 Jul 2024 10:35:06 -0400 From: Tom Lane To: depesz@depesz.com cc: ammmkilo@163.com, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #18560: Inconsistent Behavior of PostgreSQL 'LIKE' Operator In-reply-to: References: <18560-c6c21c3b8d5c3f9b@postgresql.org> Comments: In-reply-to hubert depesz lubaczewski message dated "Wed, 31 Jul 2024 11:46:46 +0200" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <3378619.1722436506.1@sss.pgh.pa.us> Date: Wed, 31 Jul 2024 10:35:06 -0400 Message-ID: <3378620.1722436506@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk hubert depesz lubaczewski writes: > On Wed, Jul 31, 2024 at 04:47:23AM +0000, PG Bug reporting form wrote: >> CREATE TABLE t0(c0 INT NOT NULL, c1 CHAR(1) UNIQUE); > I bet the thing is simply one more edge case that proves that one > shouldn't be using char(n) datatype: > https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_char.28n.29 Yeah, exactly. Some surprising choices were made way-back-when about which char(N) operations ought to ignore trailing blanks and which shouldn't. In the case at hand, a closer look shows the problem: =# explain verbose select c1,(c1 like c1) from t0; QUERY PLAN ------------------------------------------------------------- Seq Scan on public.t0 (cost=0.00..43.00 rows=2200 width=6) Output: c1, (c1 ~~ (c1)::text) There is a "char ~~ text" operator but no "char ~~ char" operator, so the parser coerces the right-hand "c1" to text --- which causes stripping of its trailing blank --- and then applies ~~, which treats the trailing blank in its left-hand argument as significant. Yes, this is arguably inconsistent, but so are a lot of other char(N) behaviors. Proposals to change anything about it have generally failed on the grounds that (1) it's not very clear what would work better and not just move the surprises around; (2) we risk breaking applications that are expecting the current behaviors; and (3) char(N) is a deprecated backwater that we shouldn't be putting any effort into. regards, tom lane