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 1vQJJv-004sK4-2n for pgsql-hackers@arkaria.postgresql.org; Tue, 02 Dec 2025 05:53:04 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vQJJu-005kpq-2M for pgsql-hackers@arkaria.postgresql.org; Tue, 02 Dec 2025 05:53:03 +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 1vQJJu-005kpi-1H for pgsql-hackers@lists.postgresql.org; Tue, 02 Dec 2025 05:53:02 +0000 Received: from mail-yx1-xb12d.google.com ([2607:f8b0:4864:20::b12d]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vQJJs-002gB4-18 for pgsql-hackers@lists.postgresql.org; Tue, 02 Dec 2025 05:53:02 +0000 Received: by mail-yx1-xb12d.google.com with SMTP id 956f58d0204a3-63fc6115d65so4184547d50.0 for ; Mon, 01 Dec 2025 21:52:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764654778; x=1765259578; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=L9jda1juYsneAZZyrasHi8H3ak82QwdJU6OMY+v4tO0=; b=Yn2798sS1aeFuqiNHAvuBMyq91u0ruJh41/IT/LMh/HcNV2r3f321KS+GPMdb8DHh7 ev37gkKiRDEmuNGDYErlYYnTq7dCVDTeLjGZmetmfVDSeoCa+DGp+5Fu1+l7bBoN2+mC 8uNgg9Aiw5AuChDKT5fqjWIyAH+2pLOaPSDN3begKM7VIf/bV0f4xR+opPO3S7ryLDBL y0Ivp4a+L8l00K9AOsvBYpGqsYp6p9GvFToWLCgZ3Q0ULTtLlvODOCDEJsB/mpH1qdY3 u+DIFd4MxxLTTOF+QJwbj7i8VjjfIE5DJyJcxvbJeSys0tK707v9cmZ6oqYb5rjrw89x ehTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764654778; x=1765259578; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=L9jda1juYsneAZZyrasHi8H3ak82QwdJU6OMY+v4tO0=; b=VPX6kKv11yfdIkzRiAnq/wxmknuIxgIju1yrWRZDuChx+u+oOz8vtzwfnUpYtQjMAt sa9178w9vOdMmbWQbrv9ujb6P97tXL3ICvefPEgoqESMMzMPu1Occ8LrvlGtMZb41kQH SMwaTIb/CWdZA7idvDfneZUCg58OQ73hXDP/sfAe7E+pYQrmd0273jnexva09wWajdes n0lGkjqiGeN/rVgBcRJHgfUTPDwIcgwSxnyYV7FjSnLKEx6Hrn6bDHH17oPf9D7be72z g50FWcztGy9CGiPReCJdCKIsnxZ7WIZn79lko83KpxdkWWsr+cr8TL+UQlYpNM0MdEJm gKHQ== X-Forwarded-Encrypted: i=1; AJvYcCW/l5xNj67b7TleVOUDNYI7LobdHsrLJvbBeZrF4jpHWpY8HjvTioSDTCDYMlRrxNH4TubZzKevVVkuE+fp@lists.postgresql.org X-Gm-Message-State: AOJu0YyptSHMHwtKMdq3u41judcNSi7XmhjIJqjPagA1Zd1MxpKH1V+R 7zRC06eLpBfJVduzWxBPM6odbxzmeSVRqI70pOhivJgxZGVzCs5Ricc4DmamQmc4/PFas1plOOi +PkRjmtHZg9JeukZtsPtPRn8anM/sqjc= X-Gm-Gg: ASbGncu/JxVc5jsI62kLmwvj2AFxMBLV0f22POu5gtdlIrCjK7h7W6pyCvQ09/tDGBm WVkDHITb0ghw4IzyHxoSxKLtAvdyStP+5hGgMhSGUdzPTcywyxsa/zvBRJfqjIjtTW+NMrIgUgp /NZCvwre/y+iaxqqJ9n7uXYNzGyR1aYhwSwe8XApECdzBTUVkwL2wo/QvIkAbp9bFgTnI1BeTgI B0HzCslEMPjpSMece3Ma5DV1pWUzeSSQAs0shrexG61NQvzCQMCubTj1cFdAEHRMASHX2EjMmQM AZYgVO2oGuBrYzKgLb+B/eY6uvo1bkS30BpV6EdAKCuNxM/04ByVM2TTNp5L2UApGI1G6+vBUz9 E8Kn30ovTHwqbLA== X-Google-Smtp-Source: AGHT+IHfFsKkFuCZUh18m1JkozmtLVES0HqTmO+mcEO05/nAtqmaQOXHqVlTI9sFbz5Oi/Ro4TM0V0sapDzjDXzanrg= X-Received: by 2002:a05:690e:120c:b0:643:1961:c600 with SMTP id 956f58d0204a3-6431961c686mr28835041d50.2.1764654778041; Mon, 01 Dec 2025 21:52:58 -0800 (PST) MIME-Version: 1.0 References: <09de6afa-c33d-4d94-a5cb-afc6cea0d2bb@illuminatedcomputing.com> <1755478.1722020334@sss.pgh.pa.us> <956f8a6f-32a7-49ab-92a3-dca5c8afe112@illuminatedcomputing.com> <1466725.1725381721@sss.pgh.pa.us> <33b10538-2c88-4278-a65f-0c1e6f265cb7@illuminatedcomputing.com> <737313.1752528083@sss.pgh.pa.us> <440458.1763858681@sss.pgh.pa.us> In-Reply-To: <440458.1763858681@sss.pgh.pa.us> From: Pavel Stehule Date: Tue, 2 Dec 2025 06:52:21 +0100 X-Gm-Features: AWmQ_bktEc-zy--8--iZ4xTm6HXIv7mJUkzTOwBm0tmSWSRVwIi4s1CEZwv_EkQ Message-ID: Subject: Re: Inline non-SQL SRFs using SupportRequestSimplify To: Tom Lane Cc: Paul A Jungwirth , Heikki Linnakangas , PostgreSQL Hackers Content-Type: multipart/alternative; boundary="00000000000032481b0644f1b58a" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000032481b0644f1b58a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi ne 23. 11. 2025 v 1:45 odes=C3=ADlatel Tom Lane napsal: > Paul A Jungwirth writes: > > The reason for supporting more than SQL functions is to let you > > construct the query dynamically, e.g. with user-supplied table/column > > names, or to only include some expensive filters if needed. This would > > be great for building functions that implement temporal > > outer/semi/antijoin. Another use-case I personally have, which I think > > is quite common, is building "parameterized views" for permissions > > checks, e.g. visible_sales(user). In that case we may only need to > > include certain joins if the user belongs to certain roles (e.g. a > > third-party sales rep). > > I went through this again, and committed it with a bunch of > mostly-cosmetic changes. In particular, it seemed like talking > about inlining "set-returning functions" is no longer really on-point, > since this mechanism is perfectly capable of inlining non-SRFs. > (The reason we haven't done that for SQL functions is mainly that > we didn't feel like doing the analysis necessary to prove that a > SELECT will return exactly one row, which would be necessary to > maintain semantic equivalence for a non-SRF after inlining. > The easy cases of that, such as "SELECT expression", are already > sufficiently handled by regular inlining.) > > So after some thought I renamed inline_set_returning_function to > inline_function_in_from, and made a bunch of other changes in names > and comments to line up with that. > > Thanks for working on this! I know it's been a long slog. > I checked this patch, and I think so using the body of the function foo_from_bar is very confusing. If I understand this patch and functionality, then the function is never executed (when the support function has support for SupportRequestInlineInFrom). +CREATE FUNCTION test_inline_in_from_support_func(internal) + RETURNS internal + AS :'regresslib', 'test_inline_in_from_support_func' + LANGUAGE C STRICT; +CREATE FUNCTION foo_from_bar(colname TEXT, tablename TEXT, filter TEXT) +RETURNS SETOF TEXT +LANGUAGE plpgsql +AS $function$ +DECLARE + sql TEXT; +BEGIN + sql :=3D format('SELECT %I::text FROM %I', colname, tablename); + IF filter IS NOT NULL THEN + sql :=3D CONCAT(sql, format(' WHERE %I::text =3D $1', colname)); + END IF; + RETURN QUERY EXECUTE sql USING filter; +END; +$function$ STABLE; More correct form should be BEGIN RAISE EXCEPTION 'halt - should not be executed directly'; END; Regards Pavel > > regards, tom lane > > > --00000000000032481b0644f1b58a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi

ne 23. 11. 2025 v=C2=A01:45 o= des=C3=ADlatel Tom Lane <tgl@sss.pg= h.pa.us> napsal:
Paul A Jungwirth <pj@illuminatedcomputing.com> writes:
> The reason for supporting more than SQL functions is to let you
> construct the query dynamically, e.g. with user-supplied table/column<= br> > names, or to only include some expensive filters if needed. This would=
> be great for building functions that implement temporal
> outer/semi/antijoin. Another use-case I personally have, which I think=
> is quite common, is building "parameterized views" for permi= ssions
> checks, e.g. visible_sales(user). In that case we may only need to
> include certain joins if the user belongs to certain roles (e.g. a
> third-party sales rep).

I went through this again, and committed it with a bunch of
mostly-cosmetic changes.=C2=A0 In particular, it seemed like talking
about inlining "set-returning functions" is no longer really on-p= oint,
since this mechanism is perfectly capable of inlining non-SRFs.
(The reason we haven't done that for SQL functions is mainly that
we didn't feel like doing the analysis necessary to prove that a
SELECT will return exactly one row, which would be necessary to
maintain semantic equivalence for a non-SRF after inlining.
The easy cases of that, such as "SELECT expression", are already<= br> sufficiently handled by regular inlining.)

So after some thought I renamed inline_set_returning_function to
inline_function_in_from, and made a bunch of other changes in names
and comments to line up with that.

Thanks for working on this!=C2=A0 I know it's been a long slog.

I checked this patch, and I think so using the= body of the function=C2=A0foo_from_bar is very confusing.
If I u= nderstand this patch and functionality, then the function is never executed= (when the support function has support for=C2=A0SupportRequestInlineInFrom= ).

+CREATE FUNCTION test_inline_in_from_support_fu= nc(internal)
+ =C2=A0 =C2=A0RETURNS internal
+ =C2=A0 =C2=A0AS :'= regresslib', 'test_inline_in_from_support_func'
+ =C2=A0 =C2= =A0LANGUAGE C STRICT;
+CREATE FUNCTION foo_from_bar(colname TEXT, tablen= ame TEXT, filter TEXT)
+RETURNS SETOF TEXT
+LANGUAGE plpgsql
+AS $= function$
+DECLARE
+ =C2=A0sql TEXT;
+BEGIN
+ =C2=A0sql :=3D fo= rmat('SELECT %I::text FROM %I', colname, tablename);
+ =C2=A0IF = filter IS NOT NULL THEN
+ =C2=A0 =C2=A0sql :=3D CONCAT(sql, format('= WHERE %I::text =3D $1', colname));
+ =C2=A0END IF;
+ =C2=A0RETUR= N QUERY EXECUTE sql USING filter;
+END;
+$function$ STABLE;

More correct form should be

BEGIN<= /div>
=C2=A0 RAISE EXCEPTION 'halt - should not be executed directl= y';=C2=A0
END;

Regards
Pavel
=C2=A0

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 regards, tom lane


--00000000000032481b0644f1b58a--