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.94.2) (envelope-from ) id 1srcPL-003H3h-Ar for pgsql-hackers@arkaria.postgresql.org; Fri, 20 Sep 2024 12:06:44 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1srcPJ-004jIs-36 for pgsql-hackers@arkaria.postgresql.org; Fri, 20 Sep 2024 12:06:42 +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.94.2) (envelope-from ) id 1srcPI-004jEt-Ne for pgsql-hackers@lists.postgresql.org; Fri, 20 Sep 2024 12:06:42 +0000 Received: from mail-ed1-x532.google.com ([2a00:1450:4864:20::532]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1srcPG-000BDP-Cy for pgsql-hackers@lists.postgresql.org; Fri, 20 Sep 2024 12:06:41 +0000 Received: by mail-ed1-x532.google.com with SMTP id 4fb4d7f45d1cf-5c251ba0d1cso2547970a12.3 for ; Fri, 20 Sep 2024 05:06:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726833999; x=1727438799; darn=lists.postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=nlcH0LeByojglzKP2vV9UgWdJladQQX5FdbZH/OxHNw=; b=DskteO0pTW2XLTnlupoB+QRFlNi92Z3bD0uJMivQ6tH5ShJ5at0zvg2RBDlhmjAQjr c7UM+UzkaumRCV0vUBnul/5uYc0xdzZbAqfAQOepyyYOTq8SC2+Zxu8XhQesz/FDLh+R wCygjQphyUPx8v8zbUe0w0KcoYcVPZR4JOGMCiOH5FoXFFn3swtoXeGf+Wgu4gVFId6o bJs5hdyM+0BiVK3fuxioxdaOiT+Ra5j6JjYBDN3HhDiG1ssxnAnJ3pVsJEco69Hd+7Kn Qkq8hgQ6bap4Hjqnd1uKFTs+RGouX7Jio8KuRBHREMGCHQVV+5N2si0LD3LrRnHhWhSU xWEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726833999; x=1727438799; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nlcH0LeByojglzKP2vV9UgWdJladQQX5FdbZH/OxHNw=; b=m+2cZr1ahR9+27c3uFOYJSKbEnc/imzJcwFyzO73F/7PnWCIcB8OgWxZuGPOhdU5KI H6zdO0tiZtDDHcPUEVbC0iJ2qF4sJysJhBrSYsimE1NcNFlnwY9a95Z/WVxii2c6GSDU nXPrznj+NP+eV2Ib5GFZ1mhItZ7zZVCpv+4z+WwtMGZW29fRGcCiQMJGeF0AZJ2lnBf4 o0v9mrkFJ1LrCNRsuiVRYZT6X0h7cZbifN8VJsTy8y9Ic4FY8rkscGcGQkJ8VCu+JbfZ b2WXiLkmGi0hWePXoZxOFyJV8Wo+Y0CnZSaETjQEnk3sIiOgn9Wyz9NqIa04ANB0SyyM 4j0A== X-Gm-Message-State: AOJu0YxPymq0bgAQHTc3uFIE7SrLSSMl/qHY1iI7E5PEigtgfr5/IzWP hIejwShLJS3vlK7a+vIAPCACcTrUqnxo6WDR9gGrQNftnBQE/HKhhanGYZ+onTgdVrteXLdpm3o hSUAAep3ZOfMvAU/ip5QVAdK2aLY= X-Google-Smtp-Source: AGHT+IE8GMLuGZRvPXRXyo1lzMyql2sPn0Y0711wMkhx0xfgFlhbmDIYaYweupBR0FNoeuZVh0udYkX8u4cEKz6ZIjI= X-Received: by 2002:a05:6402:354c:b0:5be:fbe7:11ac with SMTP id 4fb4d7f45d1cf-5c464a40709mr1593034a12.20.1726833998681; Fri, 20 Sep 2024 05:06:38 -0700 (PDT) MIME-Version: 1.0 References: <8216639.NyiUUSuA9g@aivenlaptop> <3084885.1675783797@sss.pgh.pa.us> In-Reply-To: From: Alexander Korotkov Date: Fri, 20 Sep 2024 15:06:27 +0300 Message-ID: Subject: Re: SQLFunctionCache and generic plans To: Alexander Pyhalov Cc: pgsql-hackers@lists.postgresql.org, Ronan Dunklau , Tom Lane Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, Alexander! On Tue, Sep 3, 2024 at 10:33=E2=80=AFAM Alexander Pyhalov wrote: > Tom Lane =D0=BF=D0=B8=D1=81=D0=B0=D0=BB(=D0=B0) 2023-02-07 18:29: > > Ronan Dunklau writes: > >> The following comment can be found in functions.c, about the > >> SQLFunctionCache: > > > >> * Note that currently this has only the lifespan of the calling > >> query. > >> * Someday we should rewrite this code to use plancache.c to save > >> parse/plan > >> * results for longer than that. > > > >> I would be interested in working on this, primarily to avoid this > >> problem of > >> having generic query plans for SQL functions but maybe having a longer > >> lived > >> cache as well would be nice to have. > >> Is there any reason not too, or pitfalls we would like to avoid ? > > > > AFAIR it's just lack of round tuits. There would probably be some > > semantic side-effects, though if you pay attention you could likely > > make things better while you are at it. The existing behavior of > > parsing and planning all the statements at once is not very desirable > > --- for instance, it doesn't work to do > > CREATE TABLE foo AS ...; > > SELECT * FROM foo; > > I think if we're going to nuke this code and start over, we should > > try to make that sort of case work. > > > > regards, tom lane > > Hi. > > I've tried to make SQL functions use CachedPlan machinery. The main goal > was to allow SQL functions to use custom plans > (the work was started from question - why sql function is so slow > compared to plpgsql one). It turned out that > plpgsql function used custom plan and eliminated scan of all irrelevant > sections, but > exec-time pruning didn't cope with pruning when ScalarArrayOpExpr, > filtering data using int[] parameter. > > In current prototype there are two restrictions. The first one is that > CachecPlan has lifetime of a query - it's not > saved for future use, as we don't have something like plpgsql hashtable > for long live function storage. Second - > SQL language functions in sql_body form (with stored queryTree_list) are > handled in the old way, as we currently lack > tools to make cached plans from query trees. > > Currently this change solves the issue of inefficient plans for queries > over partitioned tables. For example, function like > > CREATE OR REPLACE FUNCTION public.test_get_records(ids integer[]) > RETURNS SETOF test > LANGUAGE sql > AS $function$ > select * > from test > where id =3D any (ids) > $function$; > > for hash-distributed table test can perform pruning in plan time and > can have plan like > > Append (cost=3D0.00..51.88 rows=3D26 width=3D36) > -> Seq Scan on test_0 test_1 (cost=3D0.00..25.88 rows=3D13 > width=3D36) > Filter: (id =3D ANY ('{1,2}'::integer[])) > -> Seq Scan on test_2 (cost=3D0.00..25.88 rows=3D13 width=3D= 36) > Filter: (id =3D ANY ('{1,2}'::integer[])) > > instead of > > Append (cost=3D0.00..155.54 rows=3D248 width=3D36) > -> Seq Scan on test_0 test_1 (cost=3D0.00..38.58 rows=3D62 > width=3D36) > Filter: (id =3D ANY ($1)) > -> Seq Scan on test_1 test_2 (cost=3D0.00..38.58 rows=3D62 > width=3D36) > Filter: (id =3D ANY ($1)) > -> Seq Scan on test_2 test_3 (cost=3D0.00..38.58 rows=3D62 > width=3D36) > Filter: (id =3D ANY ($1)) > -> Seq Scan on test_3 test_4 (cost=3D0.00..38.58 rows=3D62 > width=3D36) > Filter: (id =3D ANY ($1)) > > This patch definitely requires more work, and I share it to get some > early feedback. > > What should we do with "pre-parsed" SQL functions (when prosrc is > empty)? How should we create cached plans when we don't have raw > parsetrees? > Currently we can create cached plans without raw parsetrees, but this > means that plan revalidation doesn't work, choose_custom_plan() > always returns false and we get generic plan. Perhaps, we need some form > of GetCachedPlan(), which ignores raw_parse_tree? I don't think you need a new form of GetCachedPlan(). Instead, it seems that StmtPlanRequiresRevalidation() should be revised. As I got from comments and the d8b2fcc9d4 commit message, the primary goal was to skip revalidation of utility statements. Skipping revalidation was a positive side effect, as long as we didn't support custom plans for them anyway. But as you're going to change this, StmtPlanRequiresRevalidation() needs to be revised. I also think it's not necessary to implement long-lived plan cache in the initial patch. The work could be split into two patches. The first could implement query lifetime plan cache. This is beneficial already by itself as you've shown by example. The second could implement long-lived plan cache. I appreciate your work in this direction. I hope you got the feedback to go ahead and work on remaining issues. ------ Regards, Alexander Korotkov Supabase