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 1w2uNS-000iiO-0g for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 17:08:14 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w2uNQ-00Chx1-04 for pgsql-hackers@arkaria.postgresql.org; Wed, 18 Mar 2026 17:08:12 +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 1w2uNP-00Chwt-1w for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 17:08:11 +0000 Received: from mail-ed1-x52f.google.com ([2a00:1450:4864:20::52f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w2uNL-00000000OQ2-3kHp for pgsql-hackers@lists.postgresql.org; Wed, 18 Mar 2026 17:08:10 +0000 Received: by mail-ed1-x52f.google.com with SMTP id 4fb4d7f45d1cf-6644a3029b3so251028a12.0 for ; Wed, 18 Mar 2026 10:08:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1773853688; cv=none; d=google.com; s=arc-20240605; b=VxzNgpZ4bKqtN0N+pzXri0RcF9PzRkMJB3oQncLR/mYqqee/53YUkj0mOPo9fXmFak DElP7aEJq8OYyNsUiXEM4Xgiz/Dwek7RJWyWo0AtMmfTl4Mo1H9SJmsIUAzNbdVedGu3 4KDwsv/gJgCmm6WAFxkHDLwBuKUSCrkMlqcBsJWqBcQxr+2GhI2EYoKlUrZAZAsowZQ2 qFpY/SoqJJp9UbJxiS3HAukf97cCcwIwzzEF63iqjYQCplQ1B//1mk3hJ9MXWcceQ8di 7ozcXwmvXSsRWQLyfoHdidPYsJogg0yuBsABM3zfnvbxoN2pZaWm93MvqxMQWmSHgNWU 0A0A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :dkim-signature; bh=CH+G5nY5K+0B/bKYOgp4FiWd9WczrNh/hViCw+HSIqk=; fh=b5N5TzR/96x3yFzDo8u0pMNtkFhKr6PI+Vo2ZdKXQTE=; b=AMeJUFCRGmqydZGJxs4G6qomb2TL1Yi/JEgtGRyIu8jwS+XTQpvItQLCmpVMS9ElFT rbGq+0Qnzo14Ytin8A124/373VE20TwTeYFk6ZQPFoFNdIYnXJ+k526YI5Ug/3JE0Fg+ j8hvjhxH1+KmZy+xgR5+H3qN9FRMq2hUL0+W7DdVeZdBM+/aysDwljvuJPbVBjxkCBdf zMNl+jCu5td7zdgnp6GfVFLbL6sYqz3TNTXsU5nlFthKpvC5douClvDvbOpwGaF6ZuZJ KPxxdzG2lw9sBQ31cKxt9qxaFeOTgDgYplXfU6ttgw/QuMBRcr+8yaxBTvALPXZfgMX6 vijQ==; 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=gmail.com; s=20230601; t=1773853688; x=1774458488; darn=lists.postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=CH+G5nY5K+0B/bKYOgp4FiWd9WczrNh/hViCw+HSIqk=; b=JTo6p3KyJbLGvq/MeyCYMvHZIPB3y08dFW62vy92z2e4K47cHybSxcSQm2ywwm2LKT VHGXVEW24nnpncJC7Bzvi0nuiiGM8kHYudHUZqQjBFWW1dQOI/8vmdWidWwwLk/VYOKV 2UtMLuVEUJp+qe+MZ1NWkAiq5eFEsa/dNWCCbQnjC7o2r+ZWyJsUoxpk03VS5EniuARB pS3ZDFV0NTcw63lARpWcptcRH8nQLz/BBGA4AUCn6GR+Ook9mqZ7tltPP7X+ev/UQSRd fayxx0wIdEXuM8QEJbp1bgo373hxEvOYq+BwiKXZSvv9ZxXauje6li6txq4norS8NQeQ u7jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773853688; x=1774458488; h=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=CH+G5nY5K+0B/bKYOgp4FiWd9WczrNh/hViCw+HSIqk=; b=iTgRaqrtbEZKMCHYpHvNgxMg/QJGYLe9ht44giOypo/MbxYfXqtt7AuemO1522h1FR rAiEx+VMnzNBIA5CyiJ7ItWIlv1K8+uliC6HInF5Z33FdSVMY8shhD/+GyHForAOzbYV W3wagf5wrdaDbJTmmYBi8ehxkU6I8nhIUrvngUJh2bq7Z+h75Hc9SPd+FgKfWOHBIPkL XOKH4VP7FUNcEphcEOmvTjXZ+dxqeLYcUSaBb5Cs/ZB7J8Wn6JE2fapehdCCTGfxxp5t 4eLoHSGbKeO46yW31EKXh74E+83n7VsPgSUoLSQ1eEzS1Q7GHHjzI9nYXPpUfZoJRp78 9E1Q== X-Gm-Message-State: AOJu0Yx49kLjve7a1Bo0t1/efpkCrVzGI6v4B0++KQWMm0HiUTQ8XPGT tLG6FmuPJrr0NKkBP/8jPZbbwXeiLznJLcawtcqLNWWbQsI3e6SmBRfnXpbU+6/qJf62HJLGK8B fM25imoV2EA5SAbSNETuBPTFWBBey8jRePMpz X-Gm-Gg: ATEYQzwRLOtmK05URKHzP7mSXNmvvjqiMbhaqWueFYmSygTHnFIy0gxJIuEranmbpJ8 juzF4NmHb/C3amW5mZRDnMeKg8VGEPlHkDn4VWmidrcwEuV96zYse9JPRtURrFVewETfIEqKGsF V+Ueo24HNu/tkGoRbmz4SzdHEvu7+SALU/Bc0RoxF6zRZ8BoYS+zkpq4AN29ke32VWjrwQBGRHw K/0UFy/BfREG1jMl5bitEm+fvi5dUbBdcnfBwB17cd59MJ6qbfCje8jedJ66dU13YGuFyCxDgoo 6hBZNIUV/AlpKTvRoiab4EBF9Supj35KQEvBd8/+zsMQters1w== X-Received: by 2002:a17:907:3e10:b0:b97:d561:c6a4 with SMTP id a640c23a62f3a-b97f4a5fdf8mr278506566b.37.1773853687465; Wed, 18 Mar 2026 10:08:07 -0700 (PDT) MIME-Version: 1.0 References: <1136161.1769654478@sss.pgh.pa.us> In-Reply-To: From: Robert Haas Date: Wed, 18 Mar 2026 13:07:54 -0400 X-Gm-Features: AaiRm53LygbI_AcB0g-rw5mQkFRdNxasQ51y-Hej-LVj5cjAo6zKJpc2L4zeVpI Message-ID: Subject: Re: pg_plan_advice To: PostgreSQL Hackers , Tom Lane Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, Coverity complained about the fact that pgpa_planner_feedback_warning does not do anything to free the memory used by flagbuf or detailbuf, and Tom asked whether that failure could amount to a significant leak. The best way to use a lot of memory here is to have a very long advice string that doesn't do anything useful, so I created this test case: load 'pg_plan_advice'; select set_config('pg_plan_advice.advice', v.v, false) from (select string_agg('SEQ_SCAN(hogehogehoge' || g || ')', ' ') v from generate_series(1,10000) g) v; set pg_plan_advice.feedback_warnings = true; select 1; While this is not the worst case imaginable, it's pretty bad. There's probably no use case for having 10000 advice items in your advice string even if they were all valid, and here none of them are valid for the final query (select 1). So this produces "WARNING: supplied plan advice was not enforced" with a 10000 line detail message where all the lines look like this, but with different numbers: advice SEQ_SCAN(hogehogehoge7348) feedback is "not matched" Failure to free the buffers costs us just over 1MB of memory, which is not wildly disproportionate given that the message itself is over half a MB long, so I'm not sure that freeing it is all that useful here. I don't think the context we use for planning normally sticks around for all that long. If I'm wrong about that and it does, then we should probably wrap our own shorter-lived context around the stuff this module is doing rather than trying to free allocations individually. 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. 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. 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. Thoughts? -- Robert Haas EDB: http://www.enterprisedb.com