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 1vDQLP-008dAY-Op for pgsql-hackers@arkaria.postgresql.org; Mon, 27 Oct 2025 16:45:19 +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 1vDQLO-008MoA-FV for pgsql-hackers@arkaria.postgresql.org; Mon, 27 Oct 2025 16:45:17 +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.94.2) (envelope-from ) id 1vDQLO-008Mo1-1W for pgsql-hackers@lists.postgresql.org; Mon, 27 Oct 2025 16:45:17 +0000 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vDQLK-0043l1-2F for pgsql-hackers@postgresql.org; Mon, 27 Oct 2025 16:45:16 +0000 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-33d7589774fso4734694a91.0 for ; Mon, 27 Oct 2025 09:45:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1761583513; x=1762188313; darn=postgresql.org; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date:from:to :cc:subject:date:message-id:reply-to; bh=uLihUXssmTPDvWPGjmoMVZUUYW89M4M8CLvJBKvHWuI=; b=apznnL2HFJ8D7ylauzkwTzJ4+ktofFwgR5Um3AvgKNyJTQbl8sO14CIkwIknq3dLTO JLebyztUVhtlChbPoHqd9vbvUujVN4jAeNUZAi3jKHj/BAQVHTkvn97jWochSFBGtvQI 2lgEFaPRJo1sOYr9NIy9N8gvnoAqFaPj9P3lJnCt4yzw4mH8NzDWpVqxv48W4xTfYyYq qTbhD8S0EvrX52ytaZtdtOxK0luxefvwHCV/dC9XM5GKR4Ia+9BXcSZ7FOm3BID2D6Rf laHivBPeh7Qm0v5hAdgQaiG2YCivYbHZi5ADqJrdJW1rZPWFFMdKKLG4mx3lbLNdLTEk 3lvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761583513; x=1762188313; h=in-reply-to:content-transfer-encoding:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=uLihUXssmTPDvWPGjmoMVZUUYW89M4M8CLvJBKvHWuI=; b=aQqan9ibE+zEdRSq2tGH8qdIWf9EinHJ+rRO0fZ4/Nw+5NRFiTghNow/XhwOC99Svp I/TgkV1rLcHy3ONdMWafRstb+OEAFLa15tOk5hpuP7/WRe/tnKKLIGnSZZxcL72rIlxP G30SeHwlkiqJxXnoF3EGwiqrCbUHv3Z8iW7LvdtTTg6cGY7S94la2dMLKebibVs1RkxI oTDyUAmUbIIXGf4+Z2gh3llDo32lI0SpZpirZbvJHATSMh6GcmD3KCGgiE11LwKeEUB7 WcfOyqwjkUjEWu/BNvuDZBLY3/RfLFzzFkZ1sJGYkKO3Q9EaQJwG/PhpUI+HyMGTsayv V1QQ== X-Forwarded-Encrypted: i=1; AJvYcCVcjMWgNJmOJ5LPKgJeQUg7qNcyeE90kA1EoNJNw50gOHaVCrHJ68821DC4Ee5d8m7r+SEp2uK1FenzHvQ8@postgresql.org X-Gm-Message-State: AOJu0YxNZ8Hw0k+zeu03/gqjMaRWbf0iF5BG2wazkNH8/p1lfF1ohoDV p7mYmuJD5lLT0Tlcla42H7W01bolK60nGQ3rYrPK6SBmZe37tIvyXUGD X-Gm-Gg: ASbGnct3S6RysYMBLFvPmK67lcm5IliQlPcOZP9Wvi4BgTrn2dzqIn8Q0VucdaHYcvD T3qVvCn8p6UXScuGQfkklp2D5cowaZ7RwdC3ciPFJswaXQ2I1z3DWklluDRBgpJcoSKhYMEqkDE ivXWLBOqj01Ygg1qYQ/RFlm3rL+9dGDP2dL6uFp50qGsLZ3CnyROWsDtS+DzLMF+lM2LTQa3XSw qTi1n2ZTrFBNU0gzXHiN0kRZgQqyr9AnCRtRSwVXXB8ZBACaXDInBSVsL5935SEf8PrWmGbvM3e jDG1jDnPikOE/l7d9yX43TABmstFGQj5Ksyz7LELIptWW5sJ4CwTi1lya9CX0vMSbyM8S/0ohQ/ Swb/Lkzo8M/IAGY/Rp/6OUb0Z+jH4RehVRdER0X4kyk5nusdENLF7JNFGC3RbKVqIbzmIxxfILl 2xrg/1KTxsfw+nUM5l7Nx1muLOL1uiYQ4= X-Google-Smtp-Source: AGHT+IEP4pL2KJwC6dAECYVISWqsjCw4NG+2dypdhvRTrVZ1P0pMiDyz34lMidYvmQTAr7UJVqHhAA== X-Received: by 2002:a17:90b:28c4:b0:330:6f13:53fc with SMTP id 98e67ed59e1d1-34027a98dbemr470838a91.27.1761583513497; Mon, 27 Oct 2025 09:45:13 -0700 (PDT) Received: from ltdrgnflg2 (71-34-92-171.ptld.qwest.net. [71.34.92.171]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-33fed5b522esm3692068a91.1.2025.10.27.09.45.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Oct 2025 09:45:12 -0700 (PDT) Date: Mon, 27 Oct 2025 09:45:10 -0700 From: Mark Wong To: Akshay Joshi Cc: =?iso-8859-1?Q?=C1lvaro?= Herrera , pgsql-hackers Subject: Re: [PATCH] Add pg_get_policy_ddl() function to reconstruct CREATE POLICY statement Message-ID: References: <202510151529.s3fpwsgben57@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="9ruR+s6V65BBysym" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --9ruR+s6V65BBysym Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi everyone, On Thu, Oct 16, 2025 at 01:47:53PM +0530, Akshay Joshi wrote: > > > On Wed, Oct 15, 2025 at 10:55 PM Álvaro Herrera wrote: > > Hello, > > I have reviewed this patch before and provided a number of comments that > have been addressed by Akshay (so I encourage you to list my name and > this address in a Reviewed-by trailer line in the commit message).  One > thing I had not noticed is that while this function has a "pretty" flag, > it doesn't use it to pass anything to pg_get_expr_worker()'s prettyFlags > argument, and I think it should -- probably just > >   prettyFlags = GET_PRETTY_FLAGS(pretty); > > same as pg_get_querydef() does. Kinda sorta similar thought, I've noticed some existing functions like pg_get_constraintdef make the "pretty" flag optional, so I'm wondering if that scheme is also preferred here. I've attached a small diff to the original 0001-Add-pg_get_policy_ddl-function-to-reconstruct-CREATE.patch to illustrate the additional work to follow suit, if so desired. Regards, Mark -- Mark Wong EDB https://enterprisedb.com --9ruR+s6V65BBysym Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=for-optional-pretty.diff diff --git a/doc/src/sgml/func/func-info.sgml b/doc/src/sgml/func/func-info.sgml index 4b9c661c20b..72b836cd082 100644 --- a/doc/src/sgml/func/func-info.sgml +++ b/doc/src/sgml/func/func-info.sgml @@ -3827,19 +3827,29 @@ acl | {postgres=arwdDxtm/postgres,foo=r/postgres} pg_get_policy_ddl pg_get_policy_ddl - ( table regclass, policy_name name, pretty boolean ) + ( table regclass, policy_name name , pretty boolean ) text - Reconstructs the CREATE POLICY statement from the system catalogs for a specified table and policy name. - When the pretty flag is set to true, the function returns a well-formatted DDL statement. - The result is a comprehensive CREATE POLICY statement. + Reconstructs the CREATE POLICY statement from the + system catalogs for a specified table and policy name. The result is a + comprehensive CREATE POLICY statement. + + Most of the functions that reconstruct (decompile) database objects have an + optional pretty flag, which if + true causes the result to be + pretty-printed. Pretty-printing adds whitespace for + legibility. Passing false for the + pretty parameter yields the same result as omitting + the parameter. + + diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index c05e4786703..e6d21a1d00e 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -552,6 +552,7 @@ static void get_formatted_string(StringInfo buf, bool pretty, int noOfTabChars, const char *fmt,...) pg_attribute_printf(4, 5); +static char *pg_get_policy_ddl_worker(Oid tableID, Name policyName, bool pretty); #define only_marker(rte) ((rte)->inh ? "" : "ONLY ") @@ -13788,12 +13789,41 @@ get_formatted_string(StringInfo buf, bool pretty, int noOfTabChars, const char * * policyName - Name of the policy for which to generate the DDL. * pretty - If true, format the DDL with indentation and line breaks. */ + Datum pg_get_policy_ddl(PG_FUNCTION_ARGS) +{ + Oid tableID = PG_GETARG_OID(0); + Name policyName = PG_GETARG_NAME(1); + char *res; + + res = pg_get_policy_ddl_worker(tableID, policyName, false); + + if (res == NULL) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(string_to_text(res)); +} + +Datum +pg_get_policy_ddl_ext(PG_FUNCTION_ARGS) { Oid tableID = PG_GETARG_OID(0); Name policyName = PG_GETARG_NAME(1); bool pretty = PG_GETARG_BOOL(2); + char *res; + + res = pg_get_policy_ddl_worker(tableID, policyName, pretty); + + if (res == NULL) + PG_RETURN_NULL(); + + PG_RETURN_TEXT_P(string_to_text(res)); +} + +static char * +pg_get_policy_ddl_worker(Oid tableID, Name policyName, bool pretty) +{ bool attrIsNull; int prettyFlags; Datum valueDatum; @@ -13807,7 +13837,7 @@ pg_get_policy_ddl(PG_FUNCTION_ARGS) /* Validate that the relation exists */ if (!OidIsValid(tableID) || get_rel_name(tableID) == NULL) - PG_RETURN_NULL(); + return NULL; initStringInfo(&buf); @@ -13935,5 +13965,5 @@ pg_get_policy_ddl(PG_FUNCTION_ARGS) systable_endscan(sscan); table_close(pgPolicyRel, AccessShareLock); - PG_RETURN_TEXT_P(string_to_text(buf.data)); + return buf.data; } diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 536c5a857da..3bfaf34d535 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4023,7 +4023,10 @@ prosrc => 'pg_get_function_sqlbody' }, { oid => '8811', descr => 'get CREATE statement for policy', proname => 'pg_get_policy_ddl', prorettype => 'text', - proargtypes => 'regclass name bool', prosrc => 'pg_get_policy_ddl' }, + proargtypes => 'regclass name', prosrc => 'pg_get_policy_ddl' }, +{ oid => '8812', descr => 'get CREATE statement for policy with pretty-print option', + proname => 'pg_get_policy_ddl', prorettype => 'text', + proargtypes => 'regclass name bool', prosrc => 'pg_get_policy_ddl_ext' }, { oid => '1686', descr => 'list of SQL keywords', proname => 'pg_get_keywords', procost => '10', prorows => '500', --9ruR+s6V65BBysym--