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 1w3vMN-001gYR-38 for pgsql-hackers@arkaria.postgresql.org; Sat, 21 Mar 2026 12:23:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w3vMM-00AGaB-1Q for pgsql-hackers@arkaria.postgresql.org; Sat, 21 Mar 2026 12:23:18 +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 1w3vMM-00AGa2-0B for pgsql-hackers@lists.postgresql.org; Sat, 21 Mar 2026 12:23:18 +0000 Received: from mail-yw1-x1131.google.com ([2607:f8b0:4864:20::1131]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w3vMK-00000000JyM-27F8 for pgsql-hackers@postgresql.org; Sat, 21 Mar 2026 12:23:17 +0000 Received: by mail-yw1-x1131.google.com with SMTP id 00721157ae682-79a74765703so12863717b3.3 for ; Sat, 21 Mar 2026 05:23:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1774095795; cv=none; d=google.com; s=arc-20240605; b=dgpFJfb6sevvT5Q54LIBjbnA+2fquPFasEHDLRpzXbsbnS+gH5/BQexrjvCgESgkz+ zozINjfl6GQr84oL0b58yvbCSOpLZRg2vYMcONMefrYHNuZNhJxi5SNUl1nZJfijbKl6 3IufSFPwjP9Fbb3lzDp1jfKk9CCm6Xv/KsLZCHnvTaAmqNc0hKBzBlY9kmdKKaIKyoUE 1CFn/p3ktiaabcfy2ISxNAVHNSUg4to2CqWrXwp6F0rRlTPyqTPR3B0y0y7jxGSU8vJO YwTwFkFziCsyYZ6sxekWMbY0nT4IbZ+FlVVDWvVTDQGYr1Gy+7qQvSJtpf+t91QaEMLn gEtw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:mime-version:dkim-signature; bh=RWNQtnJHljESLgsPlcguyeEcym2oozjWoEIsSjg9aec=; fh=33OU7BWuulPFH378PdKTnpeW+jw3IP20DTmpLDeQ3pE=; b=Rs6NN5SvUGQu8sVFiNRp8G7vrT0SZZrsfJ/ZlDcl6fih3ylyxP3XRpGBzSnfmid2T8 ZvlKiceRmQsDKgEu+Ik6oP89iPgkTwCZ8qQ6haYAyshi1BZuaLCMFML0PbXfFxilXuao +Y3EiLyN0JeQbNr98sCevpUG2x3E6T7I9chXPAX17kYyqNzFW63iM4rcGq//CYaRrCzS 1agg5Fa3xfftGqOmJhN8hCEahJFs+XHWI6fq041AROzciE0joOo9nfU8XlLoYa1syWCT OWwibxetI6HgDeG2OwX/89HRxltes1X4VxDQXhQwKIHwopX8uNKEf8fWYPxIeyvtZLjm P8tA==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=behn-us.20230601.gappssmtp.com; s=20230601; t=1774095795; x=1774700595; darn=postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=RWNQtnJHljESLgsPlcguyeEcym2oozjWoEIsSjg9aec=; b=b8tBLm3jut1EOP2yTLMQ5U+yFT0UvNEP4isKy9xT/N2LxGfYOLnsPyly9Iq6JjtkAb ffQCpUfJBx1BYhDS0iy+meQAKNu3buqq7xKe947EO8quweRg3QWtzDSCWX3AE8NvzB7N 9+bbhySJVJ5fx5ogLG4SgdSerD6bH7Aa8C0EsVIKTKDoGieaud4klaWDm7r08Na9ARTf gIXc8UfEnQWjltVGQUxjfR7QXS5+vhTTsQ8RBY1spz/jih2FdneAsj0akn05AkLNa9wu 2KPVco2rQiUavI47ToFVzngQuiEYu+Okf8OIY1armHWwrPyu1eA50eOlNOF6xt6cPuVa I8QA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774095795; x=1774700595; h=to:subject:message-id:date:from:mime-version:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=RWNQtnJHljESLgsPlcguyeEcym2oozjWoEIsSjg9aec=; b=AcXucm/g2ofXXfR9CFlMBJY659Aa2Y+fpJkJPcDiL2hquqQlh7g9irKuWDjTWOyS5J +BT0bWlXsugkpG2MsGBvb49ZxaM/1AuLtY5LB4xNg3fMz/Y2iPBZS52sRlOluEzYcvMs Hpe/qIl/wq3zGKi/TWdXf/rAHKRtVfU0YxYx+gzgdJvkgPDOwi+RQ4rlDc5XmD5CdA9J C34gcD/ocATU3Qd+kIBzeA31CKE0PVeQtWi/HBIe2W8BbmWsvnXLhyaVOO4npueu/xB7 wWdeIaYzJsXKYRN5jYZtZu6sHpveTKFsHU4e/3F2zqSiq7QWAClSHlxoLDKnakG2C+uh gL4A== X-Gm-Message-State: AOJu0YzmfDECu7AfcOqe7uROVJyIKosLZYopzF21ZBEv5tDKU15GZv2y r2RJ/PVrbRauNeRR587IYn9tZPBG6T2Ag4NBSUGXZU37Q9YuW0mlXvtmV6lCiTzSaRd0dUd+lKj LE78dpEk5GcBjKklOYgmLIKw1VELjA6amZm0mu1RmvfJ6fsvIRmpK0Ks= X-Gm-Gg: ATEYQzycjL5Vd+wqFfjj+2o9t5mrL2ofTtaUR7sVd8B410S51tSof+A+9QPVIgidx0Y 7rkDdqnfSb2hLo4lCZn+gzcnukfyE/9VZFEqibx+dwIcuEodSi7uRMIqtTo2V4HKfMf6/av9AJ/ uUF6hLQYm3Bh8qzFyFXgPwL5Di4QdO7J0GSxCsRkNpqJC1dpRZUlsoi+exYPaNXAikhs2j01SqL 0aQ0fDxJYrBGfwWgT9ffAoO9tg3TzyVVSdMaexIynWpbqRrt6XVyKx9ivZfURUn3hO7r+U3rckb 67fb4NtfWWg8ID8hmnh2C0T+DC/7zGAqFQBWmhFMkfjR75h/hcQ1u/6rSeSD3kxVcjc+ X-Received: by 2002:a05:690c:c4e8:b0:799:1f23:6e46 with SMTP id 00721157ae682-79a90bce86bmr66977317b3.33.1774095794963; Sat, 21 Mar 2026 05:23:14 -0700 (PDT) MIME-Version: 1.0 From: Ed Behn Date: Sat, 21 Mar 2026 08:22:38 -0400 X-Gm-Features: AaiRm522Wj_NKVYxO8N1AyQIHHAh03Aa1Ix6ZjzUFBEVR-uzSrHFBaj1t_xqwcc Message-ID: Subject: Persistent data across SETOF calls To: pgsql-hackers@postgresql.org Content-Type: multipart/alternative; boundary="000000000000a811f9064d87dd64" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a811f9064d87dd64 Content-Type: text/plain; charset="UTF-8" Good day- I maintain the PL/Haskell language handler. Typically, the handler compiles function code and stores the compiled data in the fn_extra field of FmgrInfo. The fn_extra field persists from one call to the next within a query meaning the expensive compilation only needs to happen once per query. However, when calling a set-returning function multiple times in a query, there appears to be no way to carry data from one set to another. This is because the fn_extra field stores the FuncCallContext structure. While the user_fctx field of the FuncCallContext structure persists from one call to the next, it is NULLed out at the end of a set. For example, if there is a table, t, with a column, i, and a set-returning function, func, the following query is very inefficient: SELECT * FROM t, func(i) This is because the function is recompiled for each row of t. Is there a way around this? Ideally, there would be a field that persists from one set to another within a query. Thank you for any help you can provide. -Ed --000000000000a811f9064d87dd64 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Good da= y-
=C2=A0 =C2=A0 I maintain the PL/Haskell language handler. Typically,= the handler compiles function code and stores the compiled data in the fn_= extra field of FmgrInfo. The fn_extra field persists from one call to the n= ext within a query meaning the expensive compilation only needs to happen o= nce per query.=C2=A0

=C2=A0 =C2=A0 However, when c= alling a set-returning function multiple times in a query, there appears to= be no way to carry data from one set to another. This is because the fn_ex= tra field stores the FuncCallContext structure. While the user_fctx field o= f the FuncCallContext structure persists from one call to the next, it is N= ULLed out at the end of a set.=C2=A0

=C2=A0 =C2=A0= For=C2=A0example, if there is a table, t, with a column, i, and a set-retu= rning function, func, the following query is very inefficient:
=C2=A0 =C2=A0 SELECT *
=C2=A0 =C2=A0 FROM t, func(i)=

This is because the function is recompiled for ea= ch row of t.=C2=A0

Is there a way around this? Ide= ally, there would=C2=A0be a field that persists=C2=A0from one set to anothe= r within a query.=C2=A0

Thank=C2=A0you for any=C2= =A0help you can provide.=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 -Ed
--000000000000a811f9064d87dd64--