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 1wWZHj-002hpw-1k for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 12:40:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wWZHi-002M6G-16 for pgsql-hackers@arkaria.postgresql.org; Mon, 08 Jun 2026 12:40:54 +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.96) (envelope-from ) id 1wWZHh-002M67-2h for pgsql-hackers@lists.postgresql.org; Mon, 08 Jun 2026 12:40:54 +0000 Received: from mail-qv1-xf31.google.com ([2607:f8b0:4864:20::f31]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wWZHf-00000001yDP-1lQv for pgsql-hackers@lists.postgresql.org; Mon, 08 Jun 2026 12:40:53 +0000 Received: by mail-qv1-xf31.google.com with SMTP id 6a1803df08f44-8ccf0fa0aacso62398726d6.2 for ; Mon, 08 Jun 2026 05:40:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1780922449; cv=none; d=google.com; s=arc-20240605; b=e8oMOGmAf2PkKkO+pgoDzde+LW/omnan4I7YnH8RZ7/7deG1rHfPkStGvLZi+GtSdh bVz72Scv2Y8c2OKEr5V9EH/jPJ+fUKEE9CCsrJgoY09j+lU2H3ss8dJrGr50qLCKm77+ AkhvN98Td0qCYWqV48jcuGHN6aFPMhuKBXRAASaur0natKzm8D1VNV4YnIs5qyH4yl4j mUK40R8jwZ6cBgbsGicvn6zT3QT52rX03wCc21kTVwoWYavnLnMtankmnKzyO6hj/oWI b49Ps4Ur/oVi8N8py6uq/a1y4lubA7PThHLkB6KCcLcAvbIk76XwDZOErpCVxWihMFYa Putw== 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=zCruN3fP2EBH+kx660vQ3GrCh0LHDAe1198SGQ6XPPI=; fh=vgcPBLdOPTapy+CtI1CbtQXJsrHIEHHok8mSUidHlHc=; b=TYDuzWLWFHnQzAdL3O+GRYg8GVfeeGAcfiiXBIvUgJn5u9tffS4pbjOM05iEv938eU f3gTu204NQ2YP5reRtWbqTqk7/l49jUyPVklo8zEhvWmzeBXRagjVS8mquJjbLwZo+QD 8TSarBHWm8bz5agMB9Gl4FM3rBMqrmnMLUfq1wAcJfLV0dE0HcbrsMhgHFJhwWE7XBks f5m+Xm/2XijvdBg6iQh0oZFRbTya1KbkAtGBk6xQyskTdx9qxICqXs4P6ECPxjeVaLyM sQbbkw4uUwS9X3SNysFeRWZn4kWFmCdjl5+As5kek4fn4F+pXV/kRntRS5EdjYpaeLCJ zSvw==; 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=20251104; t=1780922449; x=1781527249; 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=zCruN3fP2EBH+kx660vQ3GrCh0LHDAe1198SGQ6XPPI=; b=ZHCrsTANLnsUNNjaXm1V9L3JTrKZLixfJpRYYFukywB6xynG3WGquoZ/AwWfLNsGUm 07A1VL7SSOC77OcTWSD/sP2dCzDDKqgauDlXIdXQOjMAJUeRctPziADjLRtPfPNkBlYU vnxc1IqHr40voIHUack/UBE1DE2MQ1OwFIvZi1tz8ev/Jab2Rzj4udRqpiVXKkqgMuc8 uJU8eKGGiQjMsIn2Mfc95+/rDeU0WD2Eymp8Ipxb96Umkq4FRlMzO9mS7kyksZPMoHl8 FWUWdNc60re0cY4QpWQ2dywUZtqKCwdq4tnGzHnKrZMTp2reBHR/5+Rw+eQKYrBb0LCK Xo0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780922449; x=1781527249; 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=zCruN3fP2EBH+kx660vQ3GrCh0LHDAe1198SGQ6XPPI=; b=JkG4+FyL5l0nwhWk9gPY01XyzDmSgnigevYcEgB+2WWEKOIsG6+q1yqcwnVuNH4wg8 hdTfYda+4S2CbTr7QNNZY7I4xPZGyfL2WQN8s1KqlN4vy+9uz5R8QmEJ9g01RKIPzmEU EM9JF3Q+rHDSYE39w6ncGSuihr9ypnFZAB7BTUv+s8OS7TBAqksKkdAzdxrtkw4nyNn2 exOS1oq0EUf59ofgM+hFxZJGhaB7zLK7zgZGTvWu4QavUhTcLuiRDbgltzhh2t+i0iDI 3oYhoP4x7DchjsA/IXfo9ekLkKhIv61KKnYa3hFeS+7g79cMSCxdobrJJ9TPNclJ8hoh +VmQ== X-Forwarded-Encrypted: i=1; AFNElJ/STP3PPOtT/ZWEh+zEmZEQ5EpDauc9npLbJCQnBrAkop6LMU3TXXeIs4U2cho2QgH28usMc89U3YwIX+z2@lists.postgresql.org X-Gm-Message-State: AOJu0YzDq8BPbO9a/NtVpwjzxIpAxdsKQ0/5usjtHKj+NN+T88tn0h6C zUjN2+e0DGwQAvPxZ8H3CoVuo9yV2Le3fEpuZJvKBsCLGdT55Vas0GlTqNhxZhPwkmi8eP5uMlk WbPifN+8zmJG2LoFvYClJ+e5i+kWSNUM= X-Gm-Gg: Acq92OGa1Yl9vPoU91jtMRjff5z2ewcsQTHZnDvIWkoOhIw/TGuYaFa5Gc/JqmZ+kt/ +p6LdIkPqsYRGdAWvLdu3AJU2WHVxjRce/b4JmwUyPZs45xUInyOYpyz9KT3F24MacvRhyv/Tjr SNDsS43EUaKTVzdclv3PfuVwqyH1Pd3OKZ+B0jtGyScjmXk7q9oFIlZ8RfRqYuDXZ+k4epBZ9mX lNWySy3MHQ5ziSYnbdvL9MBoHl1s5PmBv897GqyBfrfiGRBhORbX1XBtbnrpAslORwc/ZYCbJjr FPIOCmKABk8ADtdU7E8r8n+Wi41d X-Received: by 2002:a05:6214:2125:b0:8ce:b018:89ff with SMTP id 6a1803df08f44-8cee62654c6mr249796856d6.36.1780922449142; Mon, 08 Jun 2026 05:40:49 -0700 (PDT) MIME-Version: 1.0 References: <177997571870.313758.10720313850275742354.pgcf@coridan.postgresql.org> In-Reply-To: From: solai v Date: Mon, 8 Jun 2026 18:11:12 +0530 X-Gm-Features: AVVi8CfWNid9q8_cQ21051eKh5sbH072029-uGuayp_k5tw1_n2WOwEvDUP8RU8 Message-ID: Subject: Re: [PATCH] Add pg_get_policy_ddl() function to reconstruct CREATE POLICY statement To: Akshay Joshi Cc: Ilmar Y , pgsql-hackers@lists.postgresql.org 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 all, On Mon, Jun 8, 2026 at 5:32=E2=80=AFPM Japin Li wrote= : > > On Fri, 29 May 2026 at 12:20, Akshay Joshi wrote: > > Thanks for the reviews. > > > > My original patch (v9) was actually correct. After considering Japin's = review comment, I initially thought the extra > > parentheses weren't necessary, but they are indeed required for handlin= g boolean values properly in non-pretty mode too, > > so I kept them in USING (%s) / WITH CHECK (%s) for both modes. > > > > My bad! I had not considered this situation. > > > `pg_get_expr()` only adds outer parentheses for composite expressions (= via the deparsers for `OpExpr`, `BoolExpr`, etc.). > > For atomic top-level nodes like `Const`, `Var`, `current_user`, `NULL`,= etc. > > For example: > > > > CREATE POLICY p ON t USING (true); > > SELECT pg_get_policy_ddl('t', 'p'); -- previously: ... USING true;= (syntax error) > > > > This is exactly why `pg_dump` always wraps the expression unconditional= ly; see `src/bin/pg_dump/pg_dump.c`:4473-4477: > > > > if (polinfo->polqual !=3D NULL) > > appendPQExpBuffer(query, " USING (%s)", polinfo->polqual); > > if (polinfo->polwithcheck !=3D NULL) > > appendPQExpBuffer(query, " WITH CHECK (%s)", polinfo->polwithch= eck); > > > > I've also added a round-trip regression test with `USING (true)` / `WIT= H CHECK (false)` that captures the generated DDL, > > drops the policies, re-executes the DDL, and verifies the policies are = recreated. > > > > v11 Patch attached for review. > > > > On Thu, May 28, 2026 at 7:12=E2=80=AFPM Ilmar Y w= rote: > > > > The following review has been posted through the commitfest applicatio= n: > > make installcheck-world: not tested > > Implements feature: tested, failed > > Spec compliant: not tested > > Documentation: not tested > > > > Hi, > > > > I looked at v10, focused on whether the generated CREATE POLICY statem= ent > > can be executed again. > > > > The patch applies cleanly on current master at > > 8a86aa313a714adc56c74e4b08793e4e6102b5ca. > > > > git diff --check reports no issues. > > > > I built with: > > > > ./configure --prefix=3D"$PWD/pg-install" --without-readline --without-= zlib --without-icu > > make -s -j8 > > make -s install > > > > make -C src/test/regress check TESTS=3Drowsecurity > > > > ended up running the full parallel_schedule in this makefile; all 245 = tests > > passed, including rowsecurity. > > > > I found one correctness issue in the generated non-pretty DDL. The co= de > > assumes that pg_get_expr_ext(..., false) already returns the parenthes= es > > required by CREATE POLICY syntax, but that is not true for simple bool= ean > > constants. > > > > For example: > > > > CREATE TABLE t(a int); > > CREATE POLICY p_true ON t USING (true); > > SELECT ddl FROM pg_get_policy_ddl('t', 'p_true', 'pretty', 'false') AS= ddl; > > > > returns: > > > > CREATE POLICY p_true ON public.t USING true; > > > > If I drop the policy and execute that generated statement, it fails: > > > > ERROR: syntax error at or near "true" > > LINE 1: CREATE POLICY p_true ON public.t USING true; > > ^ > > > > The same issue reproduces for WITH CHECK: > > > > CREATE POLICY p_check ON t FOR INSERT WITH CHECK (false); > > > > is reconstructed as: > > > > CREATE POLICY p_check ON public.t FOR INSERT WITH CHECK false; > > > > and executing it fails at "false". > > > > So I think USING and WITH CHECK need to be parenthesized in non-pretty= mode > > too, or the tests should include a round-trip execution check for gene= rated > > DDL with simple boolean expressions. > > > > I used two small SQL reproducers for the manual checks; the complete r= epro is > > included above. > > > > I have not reviewed the broader pg_get_*_ddl API design or every possi= ble > > policy expression form. > > > > Regards, > > Ilmar Yunusov > > > > The new status of this patch is: Waiting on Author > I reviewed and tested the V11 pg_get_policy_ddl() patch. I verified the basic functionality by creating various row-level security policies and checking the reconstructed DDL returned by pg_get_policy_ddl(). The function correctly reconstructed policies for different command types (SELECT, INSERT, UPDATE, DELETE), PERMISSIVE and RESTRICTIVE policies, multiple role lists, quoted identifiers, USING clauses, and WITH CHECK clauses. I also tested more complex cases involving subqueries. Policies containing EXISTS subqueries in both USING and WITH CHECK clauses were reconstructed successfully. Nested subqueries were also handled correctly, and I did not encounter any issues related to expression reconstruction or variable handling. I verified NULL input handling as well. Passing NULL values for the table name or policy name returned no rows as expected. Invalid relation names resulted in the expected regclass resolution error. One observation from testing is that the generated DDL omits default clauses such as FOR ALL and TO PUBLIC. For example, a policy created with FOR ALL TO PUBLIC is reconstructed without those clauses, while still producing semantically equivalent DDL. I'm not sure whether this is intentional or if the function is expected to reproduce all clauses explicitly, but it may be worth discussing. Overall, the patch worked as expected in all scenarios I tested, and I did not find any functional issues. Regards, Solai