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 1r0nlK-007uB7-0Q for pgsql-bugs@arkaria.postgresql.org; Wed, 08 Nov 2023 18:58:50 +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 1r0nlI-006uB9-EJ for pgsql-bugs@arkaria.postgresql.org; Wed, 08 Nov 2023 18:58:48 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1r0nlI-006uAz-5v for pgsql-bugs@lists.postgresql.org; Wed, 08 Nov 2023 18:58:48 +0000 Received: from momjian.us ([72.94.173.45]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1r0nlF-004brP-Cu for pgsql-bugs@lists.postgresql.org; Wed, 08 Nov 2023 18:58:46 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=momjian.us; s=2023062407; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description; bh=PJ/ysERPF7BcTods+1Key+SOM5uvzE5/Ib0CJIJP4BA=; b=4bfSD U1pDoq/ki5Mi2sFAbh2vqD+SLj+9XA67M3NdhR+Ao5+pMMTwxf55B9yMNuCeIc25hdCZOm8mpO++X vAbbqEEMHv+e0Ncn6mKbghO6skJ1CzTeTWcJ2fQTmtdS1MTMWR0NX+c6FaYWtHePtqDFN+9Suisne YO29YEjkA6MZ7gjeLoI/5cDJR72yvvqVUZjd5pp1shcay9muSvmIBub/9NBXRKa2L1rpEh5RzDHje 6Mc/G7NBXX+O90RStMpKfpJUayCntUSJeAKoQVOxxsUqpRLOZ4T57o6kRlrmyzBSKegcsIkzMwnjx QOtk3ksUentvuTB+xeMcRNqd/zRFA==; Received: from bruce by momjian.us with local (Exim 4.96) (envelope-from ) id 1r0nlD-00GVBM-2E; Wed, 08 Nov 2023 13:58:43 -0500 Date: Wed, 8 Nov 2023 13:58:43 -0500 From: Bruce Momjian To: Tomas Vondra Cc: Manuel Rigger , PostgreSQL mailing lists Subject: Re: ALTER TABLE results in "could not find cast from 3904 to 3831" Message-ID: References: <20191116235657.4ratlshjd7dt3svw@development> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191116235657.4ratlshjd7dt3svw@development> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk FYI, I can confirm this command still generates the same odd error in master. --------------------------------------------------------------------------- On Sun, Nov 17, 2019 at 12:56:57AM +0100, Tomas Vondra wrote: > On Sat, Nov 16, 2019 at 11:46:02PM +0100, Manuel Rigger wrote: > > Hi everyone, > > > > Consider the following test case: > > > > CREATE TABLE t0(c0 int4range UNIQUE, FOREIGN KEY (c0) REFERENCES t0(c0)); > > ALTER TABLE t0 ALTER c0 SET DATA TYPE int4range; -- ERROR: could not > > find cast from 3904 to 3831 > > > > Unexpectedly, the ALTER TABLE results in an error. If, for example, > > the references to the type "int4range" are replaced by "int", the two > > statements execute without error. > > > > Thanks for the report. You haven't mentioned which PostgreSQL version > you've tried this on, but I can reproduce it on 12 and I support it > affects older versions too (haven't checked though). > > This seems to be essentially an omission in how we handle polymorphic > types in ATAddForeignKeyConstraint(). That is, the same issue aplies to > int4[] for example: > > CREATE TABLE t1(c0 int4[] UNIQUE, FOREIGN KEY (c0) REFERENCES t1(c0)); > ALTER TABLE t1 ALTER c0 SET DATA TYPE int4[]; > ERROR: could not find cast from 1007 to 2277 > > There's actually this comment > > /* > * Otherwise, look for an implicit cast from the FK type to the > * opcintype, and if found, use the primary equality operator. > * This is a bit tricky because opcintype might be a polymorphic > * type such as ANYARRAY or ANYENUM; so what we have to test is > * whether the two actual column types can be concurrently cast to > * that type. (Otherwise, we'd fail to reject combinations such > * as int[] and point[].) > */ > Oid input_typeids[2]; > Oid target_typeids[2]; > input_typeids[0] = pktype; > input_typeids[1] = fktype; > target_typeids[0] = opcintype; > target_typeids[1] = opcintype; > if (can_coerce_type(2, input_typeids, target_typeids, > COERCION_IMPLICIT)) > { > pfeqop = ffeqop = ppeqop; > pfeqop_right = opcintype; > } > > And opcintype = 3831 (which is anyrange). We do get it here because the > opclass is defined like this: > > { oid => '3882', descr => 'equal', > oprname => '=', oprcanmerge => 't', oprcanhash => 't', oprleft => 'anyrange', > oprright => 'anyrange', oprresult => 'bool', oprcom => '=(anyrange,anyrange)', > oprnegate => '<>(anyrange,anyrange)', oprcode => 'range_eq', > oprrest => 'eqsel', oprjoin => 'eqjoinsel' }, > > i.e. it's a generic opclass using 'anyrange'. And can_coerce_type() does > return true, which seems fine according to the comment. > > But then a couple lines down we do this: > > old_pathtype = findFkeyCast(pfeqop_right, old_fktype, > &old_castfunc); > > which internally calls find_coercion_pathway() and that has a comment > saying this: > > /* > * find_coercion_pathway > * Look for a coercion pathway between two types. > * > * Currently, this deals only with scalar-type cases; it does not consider > * polymorphic types nor casts between composite types. (Perhaps fold > * those in someday?) > ... > */ > > So this code does not really work for polymorphic types, I'm afraid. I'm > not sure how much new code would be needed. > > regards > > -- > Tomas Vondra http://www.2ndQuadrant.com > PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services > > -- Bruce Momjian https://momjian.us EDB https://enterprisedb.com Only you can decide what is important to you.