Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1jD9LM-0004uH-10 for pgsql-hackers@arkaria.postgresql.org; Sat, 14 Mar 2020 16:08:56 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1jD9LK-0006sG-PU for pgsql-hackers@arkaria.postgresql.org; Sat, 14 Mar 2020 16:08:54 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1jD9LK-0006s9-D2 for pgsql-hackers@lists.postgresql.org; Sat, 14 Mar 2020 16:08:54 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jD9LI-0004pF-1x for pgsql-hackers@lists.postgresql.org; Sat, 14 Mar 2020 16:08:53 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id 02EG8ooo006094 for ; Sat, 14 Mar 2020 12:08:50 -0400 From: Tom Lane To: pgsql-hackers@lists.postgresql.org Subject: resolve_generic_type() is over-complex and under-correct MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <6092.1584202130.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Sat, 14 Mar 2020 12:08:50 -0400 Message-ID: <6093.1584202130@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk parse_coerce.c's resolve_generic_type() is written on the assumption that it might be asked to infer any polymorphic type's concrete type given any other polymorphic type's concrete type. This is overkill, because the only call sites look like anyelement_type =3D resolve_generic_type(ANYELEMENTOID, anyarray_type, ANYARRAYOID); subtype =3D resolve_generic_type(ANYELEMENTOID, anyrange_type, ANYRANGEOID); anyarray_type =3D resolve_generic_type(ANYARRAYOID, anyelement_type, ANYELEMENTOID); (There are two occurrences of each of these in funcapi.c, and nothing anywhere else.) But that's a good thing, because resolve_generic_type() gets some of the un-exercised cases wrong. Notably, it appears to believe that anyrange is the same type variable as anyelement: if asked to resolve anyarray from anyrange, it will produce the array over the concrete range type, where it should produce the array over the range's subtype. Rather than fix this up, I'm inclined to just nuke resolve_generic_type() altogether, and replace the call sites with direct uses of the underlying lookups such as get_array_type(). I think this is simpler to understand as well as being significantly less code. I also noticed that there's an asymmetry in funcapi.c's usage pattern: it can resolve anyelement from either anyarray or anyrange, but it can only resolve anyarray from anyelement not anyrange. This results in warts like so: regression=3D# create function foo(x anyrange) returns anyarray language s= ql as 'select array[lower(x),upper(x)]'; CREATE FUNCTION regression=3D# select foo(int4range(6,9)); foo = ------- {6,9} (1 row) -- so far so good, but let's try it with OUT parameters: regression=3D# create function foo2(x anyrange, out lu anyarray, out ul an= yarray) language sql as 'select array[lower(x),upper(x)], array[upper(x),lower(x)]'; CREATE FUNCTION regression=3D# select * from foo2(int4range(6,9)); ERROR: cache lookup failed for type 0 So that's a bug that needs fixing in any case. regards, tom lane