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.96) (envelope-from ) id 1w2YEm-000OIf-28 for pgsql-general@arkaria.postgresql.org; Tue, 17 Mar 2026 17:29:48 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2YEl-003a77-1n for pgsql-general@arkaria.postgresql.org; Tue, 17 Mar 2026 17:29:47 +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.96) (envelope-from ) id 1w2YEl-003a6z-0i for pgsql-general@lists.postgresql.org; Tue, 17 Mar 2026 17:29:47 +0000 Received: from mail-qk1-x730.google.com ([2607:f8b0:4864:20::730]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2YEi-00000000dsG-1cdg for pgsql-general@lists.postgresql.org; Tue, 17 Mar 2026 17:29:46 +0000 Received: by mail-qk1-x730.google.com with SMTP id af79cd13be357-8cd785a8783so94887085a.0 for ; Tue, 17 Mar 2026 10:29:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773768581; x=1774373381; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id:from :to:cc:subject:date:message-id:reply-to; bh=MDX4X6TyXyw9mV9O+0Qk0G+AcHdUITqmIWt11ESF5tM=; b=HmoFWCngsxmzEhLA3m6UhoN8gM0keBhcAFcIjFHxk7TBKd7QOXFUi36ON4iR7ige1B R69kh8mgk88YHoZ3EO+PovIxPtWdyrlPsiM50N9lLPpAvfhYq4Tm85X4VfdYHPjS4hBf uBMHqigTB1qgSr9rbxMg0GdkHE2mXKrQb1ZA4rGqsZVGd6SpzoEHWBH82bhnyX4THSg3 XNVt88g9y2D0PZBKpJVJyPW3jrG9RGbbAjQOrghJTIgwzLzSZHH85RWocZd2xigTh3Ft StWU/iLmi0t5CIUQGqlCuzCN7PwZJnDy1qaeR8l8X4ki1YpEnT9x36+1n1L34CqdrzJz I1vA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773768581; x=1774373381; h=content-transfer-encoding:in-reply-to:from:content-language :references:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=MDX4X6TyXyw9mV9O+0Qk0G+AcHdUITqmIWt11ESF5tM=; b=MfD203C3wJMaAqWqpF/xWeeAsipd/4yowJYdyAbZEcMrKGxNmDbsIwRuIK2ta6ITP/ HqGsXpyJla26nd4tRrPShDfkuAmCCLS9TRRRGQunLqUMwvZX2Gp/3e7zkByiy4Dpjjn3 AvMN33PCErlX4UY28Szr5MwQoz2yt9Nx3Qw2rwyQ1KHOvzGSpBskdgM/vDWUgp2AYpDY bOJt3KlFdCnnVf6M8ZTx3hcxY+8JbUSqgOdnaTB7CxBR3LmJSHZV9gV5OabfsIGHdhvT gCcZ0ptUThWVhvxqHQr0MN1JbdR8oFn4Uh6EiYjAWpzEkTXpoxDCEzqNxntX2V7a/ygL Yhhg== X-Gm-Message-State: AOJu0YzB++Jsp2EE52Bg5Vi7/ZWFlrZdUnwo9FqR4XJlIspQxFmfX2tg zWRn3/CqFV+0VrLbHI721BuFW+eJQsekk5pW3YOoUUCxrglKpeWuWVd8zTCW9ja3 X-Gm-Gg: ATEYQzyuuiW2yyH6N2gDWHPhSlBD6tOrPhcN3V7ireuEDOVW8UlQhspYK4/jltx/lon PB1Ys3WtUTdXj43515iwIn17YRZaDsPN/ouEu04vM1ZuyKfeEDit0cZ6mNglRURVYK/PsAxYdAz wLaxpkgj9Mqd3U4aumBNcj6oIT5j6wNrxUgif/Cad6SU/XpnpMRawoM6o+ZR4ojohJPpMzN8wv1 HBnNmFjQW6y2P2wG0NWxnPF1p243i6+MqABh5WLAy0vqcZ1WxMMREETNkON0T1sXvcGyEO/HvRm 3APRIJLb7NeStGURetaGOives92ihlHU/4rHKGVb30AIbsE5rUtgxbW5ZaFuiaGCP7YIk7evBME xr6fMWjmvLwDG+OR7+Tf2axdR0TPLnLseHGuAAkEIpwuo7I9EiB5mNkI04F6zKKz3kQUmOuL1gJ T516nX1lnQKtmPihACKY3AjIps7ZuXwZbhcg== X-Received: by 2002:a05:620a:2991:b0:8cd:b38c:b548 with SMTP id af79cd13be357-8cfad26ec12mr48718185a.38.1773768581282; Tue, 17 Mar 2026 10:29:41 -0700 (PDT) Received: from ?IPV6:2a07:b944::2:2? ([2a02:6ea0:e20d:2691::13]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8cfacdeb9edsm25205685a.17.2026.03.17.10.29.40 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Mar 2026 10:29:40 -0700 (PDT) Message-ID: <8e4f0d76-9e77-4819-96f7-cbc64a9d2b5a@gmail.com> Date: Tue, 17 Mar 2026 13:29:39 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: help debugging an issue with selectivity To: pgsql-general@lists.postgresql.org References: Content-Language: en-US From: Greg Hennessy In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk I am not sure if this belongs in pgsql-general or pgsql-hackers, I am trying first in psgl-general. I am trying to understand setting a selectivity function that gets applied to an operator (to hopefully provide better information for the planner/optmizer). This is for the q3c extension, source code found at https://github.com/segasai/q3c. There are functions for selectivity, and for an operator. -- A dummy type used in the selectivity operator create type q3c_type as (ra double precision, dec double precision,        ra1 double precision, dec1 double precision); -- A dummy operator function (always returns true) CREATE OR REPLACE FUNCTION q3c_seloper(double precision, q3c_type)         RETURNS bool         AS 'MODULE_PATHNAME', 'pgq3c_seloper'         LANGUAGE C STRICT IMMUTABLE COST 1000; -- A selectivity function for the q3c operator CREATE OR REPLACE FUNCTION q3c_sel(internal, oid, internal, int4)         RETURNS float8         AS 'MODULE_PATHNAME', 'pgq3c_sel'         LANGUAGE C IMMUTABLE STRICT ; -- A selectivity function for the q3c operator CREATE OR REPLACE FUNCTION q3c_seljoin(internal, oid, internal, int2, internal)         RETURNS float8         AS 'MODULE_PATHNAME', 'pgq3c_seljoin'         LANGUAGE C IMMUTABLE STRICT ; -- distance operator with correct selectivity CREATE OPERATOR ==<<>>== (         LEFTARG = double precision,         RIGHTARG = q3c_type,         PROCEDURE = q3c_seloper,         RESTRICT = q3c_sel,         JOIN = q3c_seljoin ); The C portions are declared as: /* The actual selectivity function, it returns the ratio of the  * search circle to the whole sky area  */ PG_FUNCTION_INFO_V1(pgq3c_sel); Datum pgq3c_sel(PG_FUNCTION_ARGS) where the actual calculation portion is (not showing the setup portion):         ratio = 3.14 * rad * rad / 41252.;  /* pi*r^2/whole_sky_area */         /* clamp at 0, 1*/         CLAMP_PROBABILITY(ratio);         elog(WARNING, "HERE0 pgq3c_sel.... %e", ratio);         PG_RETURN_FLOAT8(ratio); } The join function is declared as: PG_FUNCTION_INFO_V1(pgq3c_seljoin); Datum pgq3c_seljoin(PG_FUNCTION_ARGS) { where the meat portion is:        ratio = 3.14 * rad * rad / 41252.;  /* pi*r^2/whole_sky_area */         /* clamp at 0, 1*/         CLAMP_PROBABILITY(ratio);         elog(WARNING, "HERE0 pgq3c_seljoin.... %e", ratio);         PG_RETURN_FLOAT8(ratio); } The two elog statements aren't in the orig code, I've added them to help me trace the code. As far as I can tell, the these selectivity functions are called in src/backend/optimizer/path/clausesel.c in the routine clause_selectivity_ext. If I add similar elog statements, at about line 836, the code says:               if (treat_as_join_clause(root, clause, rinfo, varRelid, sjinfo))         {             /* Estimate selectivity for a join clause. */             if (opno > 6000)                 elog(WARNING, "clause_selectivity: join_selectivity opno %d",opno);             s1 = join_selectivity(root, opno,                                   opclause->args,                                   opclause->inputcollid,                                   jointype,                                   sjinfo);             if (opno > 6000){                 elog(WARNING, "join_selectivity: s1 %f", s1);             }         }         else         {             /* Estimate selectivity for a restriction clause. */             if (opno > 6000)                 elog(WARNING, "clause_selectivity: restriction_selectivity opno %d", opno);             s1 = restriction_selectivity(root, opno,                                          opclause->args,                                          opclause->inputcollid,                                          varRelid);             if (opno > 6000){                 elog(WARNING, "restriction_selectivity: s1 %lf", s1);             }         } When I actually execute this, I get output to the terminal of the form: WARNING:  join_selectivity: operator id 16818 jointype 0 0 WARNING:  HERE0 pgq3c_seljoin.... 5.873266e-12 WARNING:  datum result 4438812783922730423 0.000000 WARNING:  HERE0 pgq3c_seljoin.... 5.873266e-12 WARNING:  join_selectivity: 0.000000 16818 jointype 0 WARNING:  join_selectivity: s1 0.000000 WARNING:  clause_selectivity: s1 0.000000 where it seems to me the q3c code is returning a non zero value, but in the guts of postgres what is found is a zero value. If I want to verify I have the correct opr, which is 16818, I can verify via: q3c_test=# select oid,oprname,oprnamespace,oprowner,oprkind,oprleft,oprright,oprresult,oprcode from pg_operator where oid = 16818;   oid  | oprname  | oprnamespace | oprowner | oprkind | oprleft | oprright | oprresult |   oprcode -------+----------+--------------+----------+---------+---------+----------+-----------+-------------  16818 | ==<<>>== |         2200 |    16391 | b       |    701 |    16814 |        16 | q3c_seloper which yeilds what I expect. The join_selectivity is essentially a call in src/backend/optimizer/util/plancat.c of:     result = DatumGetFloat8(OidFunctionCall5Coll(oprjoin,             inputcollid,             PointerGetDatum(root),             ObjectIdGetDatum(operatorid),             PointerGetDatum(args),             Int16GetDatum(jointype),             PointerGetDatum(sjinfo)));     if (result < 0.0 || result > 1.0)         elog(ERROR, "invalid join selectivity: %f", result); while restriction_selectivity is a call to:     result = DatumGetFloat8(OidFunctionCall4Coll(oprrest,                     inputcollid,                     PointerGetDatum(root),                     ObjectIdGetDatum(operatorid),                     PointerGetDatum(args),                     Int32GetDatum(varRelid))); This is the point where I run out of steam. The basic issue I have is that q3c code is attempting to return a small, but non-zero value for the selectivity in two functions, but the guts of postgresql has both the join_selectivity  and restriction_selectivity function return zero where I think they shouldn't. Any advice in how to make progress on this is welcome.  I'm using 19devel (I can probably do a git merge to move to a more up to  date version), and I'm running Fedora release 43 in case which exact OS I'm using is relavent. Greg