]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
doc: Clarify that empty COMMENT string removes the comment.
authorFujii Masao <fujii@postgresql.org>
Tue, 3 Mar 2026 05:47:10 +0000 (14:47 +0900)
committerFujii Masao <fujii@postgresql.org>
Tue, 3 Mar 2026 05:47:10 +0000 (14:47 +0900)
Clarify the documentation of COMMENT ON to state that specifying an empty
string is treated as NULL, meaning that the comment is removed.

This makes the behavior explicit and avoids possible confusion about how
empty strings are handled.

Also adds regress test cases that use empty string to remove a comment.

Backpatch to all supported versions.

Author: Chao Li <lic@highgo.com>
Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: David G. Johnston <david.g.johnston@gmail.com>
Reviewed-by: Shengbin Zhao <zshengbin91@gmail.com>
Reviewed-by: Jim Jones <jim.jones@uni-muenster.de>
Reviewed-by: zhangqiang <zhang_qiang81@163.com>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/26476097-B1C1-4BA8-AA92-0AD0B8EC7190@gmail.com
Backpatch-through: 14

doc/src/sgml/ref/comment.sgml
src/test/regress/expected/create_index.out
src/test/regress/expected/create_role.out
src/test/regress/sql/create_index.sql
src/test/regress/sql/create_role.sql

index fd3f465249125f4db39bc836b2cd3c7b827309f1..bc2f02c3af3c9f7bae8668864677f9ac9de8106a 100644 (file)
@@ -80,14 +80,16 @@ COMMENT ON
   <title>Description</title>
 
   <para>
-   <command>COMMENT</command> stores a comment about a database object.
+   <command>COMMENT</command> stores, replaces, or removes the comment on a
+   database object.
   </para>
 
   <para>
-   Only one comment string is stored for each object, so to modify a comment,
-   issue a new <command>COMMENT</command> command for the same object.  To remove a
-   comment, write <literal>NULL</literal> in place of the text string.
-   Comments are automatically dropped when their object is dropped.
+   Only one comment string is stored for each object.  Issuing a new
+   <command>COMMENT</command> command for the same object replaces the
+   existing comment.  Specifying <literal>NULL</literal> or an empty
+   string (<literal>''</literal>) removes the comment.  Comments are
+   automatically dropped when their object is dropped.
   </para>
 
   <para>
@@ -265,7 +267,8 @@ COMMENT ON
     <term><replaceable class="parameter">string_literal</replaceable></term>
     <listitem>
      <para>
-      The new comment contents, written as a string literal.
+      The new comment contents, written as a string literal.  An empty string
+      (<literal>''</literal>) removes the comment.
      </para>
     </listitem>
    </varlistentry>
@@ -274,7 +277,7 @@ COMMENT ON
     <term><literal>NULL</literal></term>
     <listitem>
      <para>
-      Write <literal>NULL</literal> to drop the comment.
+      Write <literal>NULL</literal> to remove the comment.
      </para>
     </listitem>
    </varlistentry>
@@ -361,6 +364,7 @@ COMMENT ON TRANSFORM FOR hstore LANGUAGE plpython3u IS 'Transform between hstore
 COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for RI';
 COMMENT ON TYPE complex IS 'Complex number data type';
 COMMENT ON VIEW my_view IS 'View of departmental costs';
+COMMENT ON VIEW my_view IS NULL;
 </programlisting></para>
  </refsect1>
 
index d082b0b6b41efc9c88d997e7e136a9887887da01..e3e771c900e965ab7d011315ba6aa717ca7ecdca 100644 (file)
@@ -32,6 +32,20 @@ COMMENT ON INDEX six_wrong IS 'bad index';
 ERROR:  relation "six_wrong" does not exist
 COMMENT ON INDEX six IS 'good index';
 COMMENT ON INDEX six IS NULL;
+SELECT obj_description('six'::regclass, 'pg_class') IS NULL AS six_comment_is_null;
+ six_comment_is_null 
+---------------------
+ t
+(1 row)
+
+COMMENT ON INDEX six IS 'add the comment back';
+COMMENT ON INDEX six IS ''; -- empty string removes the comment, same as NULL
+SELECT obj_description('six'::regclass, 'pg_class') IS NULL AS six_comment_is_null;
+ six_comment_is_null 
+---------------------
+ t
+(1 row)
+
 --
 -- BTREE partial indices
 --
index 4e67d7276031510c98eb8b78e263c1c9e721f683..53597c5c8d9bc37f82aad104623c65dd594632ff 100644 (file)
@@ -52,6 +52,34 @@ CREATE ROLE regress_plainrole;
 CREATE ROLE regress_rolecreator CREATEROLE;
 -- ok, roles with CREATEROLE can create new roles with privilege they lack
 CREATE ROLE regress_tenant CREATEDB CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5;
+COMMENT ON ROLE regress_tenant IS 'some comment';
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NOT NULL AS has_comment;
+ has_comment 
+-------------
+ t
+(1 row)
+
+COMMENT ON ROLE regress_tenant IS NULL;
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NULL AS no_comment;
+ no_comment 
+------------
+ t
+(1 row)
+
+COMMENT ON ROLE regress_tenant IS 'add the comment back';
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NOT NULL AS has_comment;
+ has_comment 
+-------------
+ t
+(1 row)
+
+COMMENT ON ROLE regress_tenant IS ''; -- empty string removes the comment, same as NULL
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NULL AS no_comment;
+ no_comment 
+------------
+ t
+(1 row)
+
 -- ok, regress_tenant can create objects within the database
 SET SESSION AUTHORIZATION regress_tenant;
 CREATE TABLE tenant_table (i integer);
index e7d1170c8b46840f22ecd01166234a6745454083..83dfdbf32d5f89b56bebd3fef4a2f5b989b284cc 100644 (file)
@@ -45,6 +45,10 @@ CREATE INDEX six ON shighway USING btree (name text_ops);
 COMMENT ON INDEX six_wrong IS 'bad index';
 COMMENT ON INDEX six IS 'good index';
 COMMENT ON INDEX six IS NULL;
+SELECT obj_description('six'::regclass, 'pg_class') IS NULL AS six_comment_is_null;
+COMMENT ON INDEX six IS 'add the comment back';
+COMMENT ON INDEX six IS ''; -- empty string removes the comment, same as NULL
+SELECT obj_description('six'::regclass, 'pg_class') IS NULL AS six_comment_is_null;
 
 --
 -- BTREE partial indices
index 292dc087975860f0957a3b1275270bc7154c772b..5841b57e7cba3b7b841f3278a206ab7207e5b1b3 100644 (file)
@@ -55,6 +55,14 @@ CREATE ROLE regress_rolecreator CREATEROLE;
 
 -- ok, roles with CREATEROLE can create new roles with privilege they lack
 CREATE ROLE regress_tenant CREATEDB CREATEROLE LOGIN INHERIT CONNECTION LIMIT 5;
+COMMENT ON ROLE regress_tenant IS 'some comment';
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NOT NULL AS has_comment;
+COMMENT ON ROLE regress_tenant IS NULL;
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NULL AS no_comment;
+COMMENT ON ROLE regress_tenant IS 'add the comment back';
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NOT NULL AS has_comment;
+COMMENT ON ROLE regress_tenant IS ''; -- empty string removes the comment, same as NULL
+SELECT shobj_description('regress_tenant'::regrole, 'pg_authid') IS NULL AS no_comment;
 
 -- ok, regress_tenant can create objects within the database
 SET SESSION AUTHORIZATION regress_tenant;