Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mUxWP-0006G1-Ha for pgsql-performance@arkaria.postgresql.org; Mon, 27 Sep 2021 20:46:45 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mUxWM-0002gg-UW for pgsql-performance@arkaria.postgresql.org; Mon, 27 Sep 2021 20:46:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mUxWM-0002gX-MN for pgsql-performance@lists.postgresql.org; Mon, 27 Sep 2021 20:46:42 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mUxWJ-0007OV-Mw for pgsql-performance@lists.postgresql.org; Mon, 27 Sep 2021 20:46:41 +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 18RKkUGr2770840; Mon, 27 Sep 2021 16:46:30 -0400 From: Tom Lane To: Kim Johan Andersson cc: pgsql-performance@lists.postgresql.org Subject: Re: Partial index on enum type is not being used, type issue? In-reply-to: <9a51090e-e075-4f2f-e3a6-55ed4359a357@kimmet.dk> References: <9a51090e-e075-4f2f-e3a6-55ed4359a357@kimmet.dk> Comments: In-reply-to Kim Johan Andersson message dated "Mon, 27 Sep 2021 22:02:49 +0200" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <2770838.1632775590.1@sss.pgh.pa.us> Date: Mon, 27 Sep 2021 16:46:30 -0400 Message-ID: <2770839.1632775590@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Kim Johan Andersson writes: > [ uses partial index: ] > EXPLAIN (analyze, costs, buffers, verbose) SELECT val FROM > table_test_enum WHERE val = 'Ole' and dat IS NULL; > > [ doesn't: ] > PREPARE qry1(varchar) AS SELECT val FROM table_test_enum WHERE val = > $1::type_table_test_enum AND dat IS NULL; There's no actual cast from varchar to that enum type. The system is letting you get away with it anyway, by applying what's called a CoerceViaIO cast --- which means convert the varchar to a simple string (cstring) and then apply enum_in(). Unfortunately for you, enum_in() is marked stable not immutable (probably on the grounds that it depends on catalog contents) so the expression isn't reduced to a plain constant during constant-folding and thus fails to match the partial index's WHERE clause. In the first case, 'Ole' is taken as a constant of type type_table_test_enum right off the bat, as was the same constant in the index's WHERE clause, so everything matches fine. (This seems a little inconsistent now that I think about it --- if it's okay to fold the literal to an enum constant at parse time, why can't we do the equivalent at plan time? But these rules have stood for a good while so I'm hesitant to change them.) Anyway, the recommendable solution is the one you already found: declare the PREPARE's argument as type_table_test_enum not varchar. regards, tom lane