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 1w2w84-000kFY-1g for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 19:00:28 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2w82-00DT4Y-2Q for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 19:00:26 +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 1w2w82-00DT4Q-0y for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 19:00:26 +0000 Received: from mail-qv1-xf29.google.com ([2607:f8b0:4864:20::f29]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2w7y-00000000PVw-2PNS for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 19:00:25 +0000 Received: by mail-qv1-xf29.google.com with SMTP id 6a1803df08f44-89c5340fed0so2050396d6.0 for ; Wed, 18 Mar 2026 12:00:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773860423; cv=none; d=google.com; s=arc-20240605; b=Ey3wK9MAVJ0OBzvUBntMjHmjvSN1nsI8FBjf3LCHnqBb1NBTJQhXGuNCQba9sLNYEM 44qEZGBlpE4VDhlT9qcQu9A9we+CQXYfMoCA/rcD2RZInU4qrH/iv8iWkalA9P5adEJ1 R1/+zcTlHnn4zdJiME/MMWHfFvoa+1RMYc3uYYXwNoDgmsHEBB06s08eM5x6tQn4dMXW yMQUMFy6k0JBxFapBCOk4yst39SxjjeRaX2GkVjKeASwcB/YCfJdOpCH3LwNrbQikTeo NJiQp8OwdMSJ5UaSmRc0vRB7Td3anw09uq/rPKRn7TqeVr3tLoYtGflCimCSBuBEv8sw PNuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=3uymAPnAO0fj8DEuJT1cihMwxCncijn6Lb+UaVeC8NU=; fh=nzIzFYeX+pSVzPPyy5cR0DW7Vqk9azWaG0wrU8LGpNk=; b=FnYqY9p1JgaG9RD6dU6K+i6KNybcTYmS0bXURnIx1LRY/rEZ67Ibu5iLlmbDAhgcS0 91vakZ9RSXznq9yQImbqmA1PqPp7L2DSu7DPHhjQ++qSl/QxLalrOV8JNKrOzacrHYFT aUp8V5mOTxWeQFRNgomH/o8I6h/rci8sG5ME6jkqYo0s7gKipdmR1Y5rokbrvCgSRwZh cc5gDhWTWpdJAIQIJPuNbeZoCVf2N9ISviI1IJOko2OtLjkpSyx6DKe9ZYUKAVk09QOD 2bqY3jcZCIyF23a/HXryTxDHPOJv6TrZvhsb/YflcEJhuBA47wNKA1eguw7qrc8msZ05 6CHQ==; darn=lists.postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fittl.com; s=google; t=1773860423; x=1774465223; 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=3uymAPnAO0fj8DEuJT1cihMwxCncijn6Lb+UaVeC8NU=; b=UYCp5dPML/nEpPkzxBdN0NcA8RpliDP4v6HPAd1Gt34kvl4q4RO0xTWOemX4iT63Rh yEtP1pEWI+8NFJhp7Pu328qFaARf1qv2MDBKO+nCkHYg2iGxs4lD+J+LFWcEDpl+K0BO E1eFVGAzjeJkvvHw3R+Li06hHXQIeJP0Vd0W0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773860423; x=1774465223; h=content-transfer-encoding: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=3uymAPnAO0fj8DEuJT1cihMwxCncijn6Lb+UaVeC8NU=; b=GIu4Gt3l2GPwizd0+cI3D+E7bcI/IuzbjepNDo0XZGJ5iY0c31vxRICAlHSB7btmap NeI/S7tQS/4/8kKqfC2VNomEH1GCTGFTa04kW5MQ8z5MJWnOyd2IKxXQ6Es0s4UiHsKi Rvj8ZXvHW+K7Vgy0LpH/yb6xWKKVaK7Y13LnCsjEmceZinnV6jNMlZUtoJsq1nd9TAcW BUZAG51VZCPYkLekS2+Eg9CwW8bQIuYyjlhY1vuFQRp/VaFXKdBwLHBHXtri/3HR+nxN OAsMhXGoA+7tV88VRIrXQgKml6QSLX3PLpKZVpfdp6sGTrgDHmdfxqbKelBl217IiDqC wN3A== X-Gm-Message-State: AOJu0YyN1HZmDHwMBX4efUXLj3R6GDja7UUMKxwXEVc0ovP8sw+eRIz3 KLkXPEvkn0pMU7CSvMyzEOhEteyoOzs4IeKZNqt5fqIV0fCYYhoUm0D3rOgzbAVzVJ7D9AJ60kq OOlOXOQSLcuCBLVZnCq436DkKKY7vQRkBFZ0JOYEi X-Gm-Gg: ATEYQzxd0IhFO0mw0y6rJKC6TEAq8iO2FJ+8Hf46Dogd34eB5VOciUI0ABdJdnL11q2 fxWD2tkm5/QMwH0V48FYS42NJ+slS+qJbC9riwZwznNOrqZyKLO9kW2bXBB1YACYvB2OfZKr1fi TYoah1noKmwcIuugESu7SUwFd28dq40z5iBMIUZpRAyx+rZ3WGpg6FdNkqsxk5xZf9W7FjH6+d7 xVapVhBkKF/jbbJ2UZA29jUlCzCX+QdMVrDR8tlDzCGdJQtrjfOa7/PI83M82KKH+W56Z2q4jYs JVE9fxzILxcAEPZ9eQQFVHmljXd2MOBpGitQU2WvQrQYgLRoEIbahD41suoWel0eFo5incRj X-Received: by 2002:a05:6214:242a:b0:89c:42ef:50e9 with SMTP id 6a1803df08f44-89c7742c97emr10500226d6.16.1773860423008; Wed, 18 Mar 2026 12:00:23 -0700 (PDT) MIME-Version: 1.0 References: <1136161.1769654478@sss.pgh.pa.us> In-Reply-To: From: Lukas Fittl Date: Wed, 18 Mar 2026 11:59:46 -0700 X-Gm-Features: AaiRm51PPLaz6FTfb9mgXNsjexGeBIKlB5I2LKt7ToaXZVBnpL8uSVO5F3YNpVU Message-ID: Subject: Re: pg_plan_advice To: Robert Haas Cc: PostgreSQL Hackers , 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 On Wed, Mar 18, 2026 at 10:08=E2=80=AFAM Robert Haas wrote: > But this does raise two points which are perhaps worthy of some > further consideration: > > 1. Maybe we should limit the length of the detail message. In some > other cases, like reportDependentObjects, we limit the detail message > to the first 100 problems found, and then say at the end of that > detail message how many more problems there were afterwards. We could > do that here, too. I'm not 100% sure it's worth the code, but then > again it's not much code. I think we have similar problems elsewhere in Postgres where a large user input causes an even larger log output - e.g. a case I'm familiar with are complicated queries with long IN list inputs and their associated EXPLAIN plans being logged by auto_explain - I recently had a case where someone reported an OOM due to auto_explain trying to log a > 100 MB sized query plan. I think its actually less a problem with plan advice, since presumably we won't have ORMs generating plan advice, and even if we do it'd be per-table - so I think its unlikely a genuine use case would use 1000s of advice tags. That said, I also don't think super long long messages are actually helpful. I do wonder if we should have a more coarse GUC that limits DETAIL lines of any kind to a maximum length (e.g. 100 kB) across the board instead of special casing every emitter. > 2. The way the current code works is to transform the advice feedback > into a Node-tree representation which is stashed in the PlannedStmt's > extension_state, and then also passes that Node-tree representation to > pgpa_planner_feedback_warning, which generates the actual warning. > That Node-tree representation is currently used by EXPLAIN to display > the advice feedback, which I think for most people will be a nicer > interface than enabling pg_plan_advice.feedback_warnings, and it can > also be used by other extensions. For instance, we could extend > pg_stash_advice so that it looks at the advice feedback and updates > the shared store, so that users can monitor whether their stashed > advice is doing what they hoped it would. Yeah, I think the ability for other extensions to retrieve this is pretty important - whether in pg_stash_advice, or any other kind of plan management extension that wants to know the outcome of applied advice. > > However, in a case like this, that Node tree is actually quite large: > about 16MB. I guess that's because pgpa_planner_append_feedback() has > to do multiple allocations for every item of feedback: a C string, > DefElem, an Integer, plus whatever lappend() charges us to add to a > List. We could save that memory by adding code here to optimize for > the case where we need to generate warnings but we don't need the Node > tree for anything else. I'm inclined not to do that, because (A) I > don't think temporarily using 16MB when the user specifies 10,000 > items of bogus advice is really that bad and (B) complicating the code > has its own costs, such as maybe introducing more bugs. However, maybe > someone else sees it differently. > > Another idea is to try to find a more economic Node representation. > For instance, we could jam the flags into the DefElem's location > field, instead of building a separate Integer node, or we could build > the advice feedback as a giant binary blob and wrap it in a varlena > and a Const node and leave consumers to make sense of that as best > they're able, or we could invent a new Node type that's just to the > perfect thing to hold a C string and an integer. I'm inclined to think > that the first two are too hacky and the third is too special-purpose, > but again someone else might see it otherwise. Yeah, I feel like we're definitely constrained here by the fact that advice tags are defined by a contrib module vs in-core - if they were in-core we could just add a dedicated node type for them. I don't think inventing a specialized binary format only defined in the contrib module makes sense. Two other ideas: 1) What if we return the utilized advice string as a separate DefElem with a list of strings, and then the feedback just has to reference an index into that list? (though I suppose that doesn't actually save memory, now that I think that through -- unless we assume the caller already has the advice string, but I don't think we can rely on that) 2) We could consider having separate DefElems for the different flag types (i.e. "feedback_failed", "feedback_match_full", etc), and then a list of strings attached to each - that'd save the nested DefElem and the Integer node Thanks, Lukas --=20 Lukas Fittl