postgres.git / summary / log / commit / refs
commit 02dc089bf1560c391fc295dbfaaf0d4a13d178b7
Author: Bruce Momjian <bruce@momjian.us>
Date: Fri Dec 26 22:34:17 2025 +0000
First released in: 17.8, 18.2
doc: warn about the use of "ctid" queries beyond the examples
Also be more assertive that "ctid" should not be used for long-term
storage.
Reported-by: Bernice Southey
Discussion: https://postgr.es/m/CAEDh4nyn5swFYuSfcnGAbpQrKOc47Hh_ZyKVSPYJcu2P=51Luw@mail.gmail.com
Backpatch-through: 17
doc/src/sgml/ddl.sgml | 2 +-
doc/src/sgml/ref/delete.sgml | 3 +++
doc/src/sgml/ref/update.sgml | 3 +++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index a00e496798f..45aba211339 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -1468,7 +1468,7 @@ CREATE TABLE circles (
locate the row version very quickly, a row's
<structfield>ctid</structfield> will change if it is
updated or moved by <command>VACUUM FULL</command>. Therefore
- <structfield>ctid</structfield> is useless as a long-term row
+ <structfield>ctid</structfield> should not be used as a row
identifier. A primary key should be used to identify logical rows.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/delete.sgml b/doc/src/sgml/ref/delete.sgml
index 7717855bc9e..f61ecc7881b 100644
--- a/doc/src/sgml/ref/delete.sgml
+++ b/doc/src/sgml/ref/delete.sgml
@@ -285,6 +285,9 @@ DELETE FROM user_logs AS dl
USING delete_batch AS del
WHERE dl.ctid = del.ctid;
</programlisting>
+ This use of <structfield>ctid</structfield> is only safe because
+ the query is repeatedly run, avoiding the problem of changed
+ <structfield>ctid</structfield>s.
</para>
</refsect1>
diff --git a/doc/src/sgml/ref/update.sgml b/doc/src/sgml/ref/update.sgml
index 1c433bec2bb..456d03a0104 100644
--- a/doc/src/sgml/ref/update.sgml
+++ b/doc/src/sgml/ref/update.sgml
@@ -470,6 +470,9 @@ UPDATE work_item SET status = 'failed'
WHERE work_item.ctid = emr.ctid;
</programlisting>
This command will need to be repeated until no rows remain to be updated.
+ (This use of <structfield>ctid</structfield> is only safe because
+ the query is repeatedly run, avoiding the problem of changed
+ <structfield>ctid</structfield>s.)
Use of an <literal>ORDER BY</literal> clause allows the command to
prioritize which rows will be updated; it can also prevent deadlock
with other update operations if they use the same ordering.
[parent: 862ed6e4983a]