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 1w2evd-000TzZ-33 for pgsql-general@arkaria.postgresql.org; Wed, 18 Mar 2026 00:38:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2evb-006E4D-1N for pgsql-general@arkaria.postgresql.org; Wed, 18 Mar 2026 00:38:27 +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.96) (envelope-from ) id 1w2eva-006E45-2Y for pgsql-general@lists.postgresql.org; Wed, 18 Mar 2026 00:38:27 +0000 Received: from mail-dy1-x132d.google.com ([2607:f8b0:4864:20::132d]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2evX-00000000H45-1c0C for pgsql-general@lists.postgresql.org; Wed, 18 Mar 2026 00:38:25 +0000 Received: by mail-dy1-x132d.google.com with SMTP id 5a478bee46e88-2b6b0500e06so7542900eec.1 for ; Tue, 17 Mar 2026 17:38:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773794304; x=1774399104; darn=lists.postgresql.org; h=to:in-reply-to:cc:references:message-id:date:subject:mime-version :from:content-transfer-encoding:from:to:cc:subject:date:message-id :reply-to; bh=EGOiGpcf8v+GVZwRDbPmNXn1uijBioCSXlDvLdOCMhs=; b=E5niGKZa2Cl+UvA8ppt5R3uxSTYz3qoW+j+mSRT5NiDakrfOpN6KRipuyWzrrQUal4 +/I9w+gLeaRtrFcPIqxWA2OfAwaadxPp0kCXXBeuXWTil+WcdmArzOFSTlr2vN/bLsDv ZVeOp1DnptYGfLUkMwzqn97onOZm8mePUNoWB/Vu88JG4nlUeqzd8jrQhP7rMtY4JZOl DLmFYkGQMZiDJlNhv5uxl8UydY/doFZAH/tNE+2cu8M/lTi5SRUKFkkY7pt3WEXzTRft 7cZ98W5vyA5ww3/38RcW7bGVgwlwTNhIrlJv0t+B0JHwoIyjOn3lXK4sgMf6EQ2ZkYmx 2ycw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773794304; x=1774399104; h=to:in-reply-to:cc:references:message-id:date:subject:mime-version :from:content-transfer-encoding:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=EGOiGpcf8v+GVZwRDbPmNXn1uijBioCSXlDvLdOCMhs=; b=AWSFWpq5/actxyC0Uh163eqFEEJTVlYxPtDZzI+lIJjhDVbaOBs0z8QlB3KhA4vdxk 08pW6OwNyLFT8fcWFSj3uhItdhtYwiD8iRHWX8WZa4m+/5xdZS0ZZ/cggFrpmOXO+tZh 6BAgsgSNdBsByHl0WZqo+Cz6jaHqqsXYPLhlqPbX1ztPfd/bco5TEO2F5Qfqb4h9F8C1 T8OqT+MbcSAcXAiefwPxCSJ+0s/RxJiaM2vAhtzE+yQKhk3VpqlVKIC3/tdNXP1TlPs8 QCQ2eufU4oJbgP4qg9fpv/Rj7wPb45LAExRm5wpo1lK+AxuGFl03vja9doHO3QGm4zs3 zn4A== X-Gm-Message-State: AOJu0YwuHjidh81JpHf4ZpQtSqaX9SF6jbx8npbNcy3Ja7rsb++tei89 6+ehZx1klo6s4sHs4Vd4RLAmtql7iE73OmkMGQTeUJN52Fb82PxZ7Gf8CDyS4w== X-Gm-Gg: ATEYQzx7UNRHWDQ3VWhkCg0ovh1s1ThAXC2DagvxVJd0fdHvTFUqADY3sr/9pKhx8CD 0Xl/COdoMHKPsD6pevFeYKrn94a8UERNikhrRckbuSwVl/LTv/PnCFYdXhGaP1MKUfovfdqBj4x ZRG4QKvhR5cRVQBhgKppHSHtBkL2p7OE79D4UoUcDKMNYgZL8puZSs0QxgbX7o1hSSFR/TnsLOV VbnqijkDUe6HdVjcSMvCC35PIDGMAU9Nlm3BtnAhveM7V57oAC+wkLpdtTXpUVFiSfxHIUtW9vO 8SII00ieJHzLmAKrPtyTgApO9PX4lV4tT03xT58J+YFXm850VH34m/ofZBObSk4tjcbO2wtfQip DaJwNAN/qrjsXf8ipgaeFhlRrjMzeJNL0GZDI1c1IR8F6BRNIzF0nmadqMjmEGHFz1EG5w/730i +5qlYIuQf/wdsrwKEgm2UrtNTxa035Ulxf/itZusc4JqF+YEDhPF/WFyGw X-Received: by 2002:a05:7300:a887:b0:2c0:d04c:a6a6 with SMTP id 5a478bee46e88-2c0e507ed22mr729805eec.6.1773794303496; Tue, 17 Mar 2026 17:38:23 -0700 (PDT) Received: from smtpclient.apple ([2601:681:4c01:7310:8421:d363:dbd3:8ab0]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2c0e55a0d4asm1563867eec.20.2026.03.17.17.38.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 17 Mar 2026 17:38:22 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: Rob Sargent Mime-Version: 1.0 (1.0) Subject: Re: help debugging an issue with selectivity Date: Tue, 17 Mar 2026 18:38:11 -0600 Message-Id: References: <8e4f0d76-9e77-4819-96f7-cbc64a9d2b5a@gmail.com> Cc: pgsql-general@lists.postgresql.org In-Reply-To: <8e4f0d76-9e77-4819-96f7-cbc64a9d2b5a@gmail.com> To: Greg Hennessy X-Mailer: iPhone Mail (23D8133) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk /=E2=80=94 intentional top post=E2=80=94/ Have you been a very bad boy and usurped an existing email thread? > On Mar 17, 2026, at 11:29=E2=80=AFAM, Greg Hennessy wrote: >=20 > =EF=BB=BFI am not sure if this belongs in pgsql-general or pgsql-hackers, I= am trying first in psgl-general. >=20 > 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 e= xtension, source code found at > https://github.com/segasai/q3c. >=20 > There are functions for selectivity, and for an operator. >=20 > -- 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); >=20 > -- 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; >=20 > -- 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 ; >=20 > -- A selectivity function for the q3c operator > CREATE OR REPLACE FUNCTION q3c_seljoin(internal, oid, internal, int2, inte= rnal) > RETURNS float8 > AS 'MODULE_PATHNAME', 'pgq3c_seljoin' > LANGUAGE C IMMUTABLE STRICT ; >=20 > -- distance operator with correct selectivity > CREATE OPERATOR =3D=3D<<>>=3D=3D ( > LEFTARG =3D double precision, > RIGHTARG =3D q3c_type, > PROCEDURE =3D q3c_seloper, > RESTRICT =3D q3c_sel, > JOIN =3D q3c_seljoin > ); >=20 > The C portions are declared as: >=20 > /* 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) >=20 > where the actual calculation portion is (not showing the setup portion): >=20 > ratio =3D 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); > } >=20 > The join function is declared as: > PG_FUNCTION_INFO_V1(pgq3c_seljoin); > Datum pgq3c_seljoin(PG_FUNCTION_ARGS) > { >=20 > where the meat portion is: > ratio =3D 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); > } >=20 > The two elog statements aren't in the orig code, I've added them to help m= e 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_e= xt. > If I add similar elog statements, at about line 836, the code says: >=20 > if (treat_as_join_clause(root, clause, rinfo, varRelid, sjin= fo)) > { > /* Estimate selectivity for a join clause. */ > if (opno > 6000) > elog(WARNING, "clause_selectivity: join_selectivity opno %= d",opno); > s1 =3D 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 =3D restriction_selectivity(root, opno, > opclause->args, > opclause->inputcollid, > varRelid); > if (opno > 6000){ > elog(WARNING, "restriction_selectivity: s1 %lf", s1); > } > } >=20 >=20 > 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 >=20 > where it seems to me the q3c code is returning a non zero value, but in th= e guts of > postgres what is found is a zero value. If I want to verify I have the cor= rect opr, > which is 16818, I can verify via: > q3c_test=3D# select oid,oprname,oprnamespace,oprowner,oprkind,oprleft,oprr= ight,oprresult,oprcode from pg_operator where oid =3D 16818; > oid | oprname | oprnamespace | oprowner | oprkind | oprleft | oprright= | oprresult | oprcode > -------+----------+--------------+----------+---------+---------+---------= -+-----------+------------- > 16818 | =3D=3D<<>>=3D=3D | 2200 | 16391 | b | 701 | = 16814 | 16 | q3c_seloper >=20 > which yeilds what I expect. >=20 > The join_selectivity is essentially a call in src/backend/optimizer/util/p= lancat.c of: > result =3D DatumGetFloat8(OidFunctionCall5Coll(oprjoin, > inputcollid, > PointerGetDatum(root), > ObjectIdGetDatum(operatorid), > PointerGetDatum(args), > Int16GetDatum(jointype), > PointerGetDatum(sjinfo))); >=20 > if (result < 0.0 || result > 1.0) > elog(ERROR, "invalid join selectivity: %f", result); >=20 > while restriction_selectivity is a call to: > result =3D DatumGetFloat8(OidFunctionCall4Coll(oprrest, > inputcollid, > PointerGetDatum(root), > ObjectIdGetDatum(operatorid), > PointerGetDatum(args), > Int32GetDatum(varRelid))); >=20 > 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 func= tion return zero where > I think they shouldn't. >=20 > 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 r= elease 43 in case which > exact OS I'm using is relavent. >=20 > Greg >=20 >=20 >=20