diff --git a/docs/cql/dml/select.rst b/docs/cql/dml/select.rst
index 5e05111eb8..0146d6e75b 100644
--- a/docs/cql/dml/select.rst
+++ b/docs/cql/dml/select.rst
@@ -117,11 +117,15 @@ set will be that of the alias. For instance::
clause, not in the ``ORDER BY`` clause, ...). You must use the original column name instead.
+.. _select-writetime-ttl:
+
``WRITETIME`` and ``TTL`` function
```````````````````````````````````
Selection supports two special functions (which aren't allowed anywhere else): ``WRITETIME`` and ``TTL``. Both functions
-take only one argument, and that argument *must* be a column name (so, for instance, ``TTL(3)`` is invalid).
+take only one argument, which must be either a column name, a subscript expression of the form ``collection_column[element]``
+for an individual element of a non-frozen map or set collection, or a field selection of the form ``udt_column.field``
+for an individual field of a non-frozen user-defined type column (so, for instance, ``TTL(3)`` is invalid).
Those functions let you retrieve meta-information that is stored internally for each column, namely:
@@ -131,7 +135,60 @@ You can read more about the ``TIMESTAMP`` retrieved by ``WRITETIME`` in the :ref
- ``TTL`` retrieves the remaining time to live (in *seconds*) for the value of the column, if it set to expire, or ``null`` otherwise.
-You can read more about TTL in the :doc:`documentation ` and also in `this ScyllaDB University lesson `_.
+You can read more about TTL in the :doc:`documentation ` and also in `this ScyllaDB University lesson `_.
+
+**Using** ``WRITETIME`` **and** ``TTL`` **on map and set collection elements**
+
+For a non-frozen map or set column, each element is stored as an independent cell and may have its own write timestamp and TTL.
+You can retrieve the per-element timestamp or TTL by subscripting the column with the element::
+
+ -- Create a table with a map column and a set column
+ CREATE TABLE t (pk int PRIMARY KEY, m map, s set);
+
+ -- Insert elements with an explicit timestamp
+ INSERT INTO t (pk, m, s) VALUES (1, {1: 10, 2: 20}, {1, 2}) USING TIMESTAMP 1000000;
+
+ -- Update one element with a newer timestamp
+ UPDATE t USING TIMESTAMP 2000000 SET m = m + {2: 30}, s = s + {3} WHERE pk = 1;
+
+ -- WRITETIME(m[key]) returns the write timestamp of that specific map element
+ SELECT WRITETIME(m[1]), WRITETIME(m[2]) FROM t WHERE pk = 1;
+ -- Returns: 1000000 | 2000000
+
+ -- WRITETIME(s[element]) returns the write timestamp of that specific set element
+ SELECT WRITETIME(s[1]), WRITETIME(s[3]) FROM t WHERE pk = 1;
+ -- Returns: 1000000 | 2000000
+
+ -- TTL(m[key]) returns the remaining TTL of that specific map element
+ INSERT INTO t (pk, m) VALUES (1, {1: 10}) USING TTL 3600;
+ SELECT TTL(m[1]) FROM t WHERE pk = 1;
+ -- Returns the remaining TTL in seconds for element m[1]
+
+Note that ``WRITETIME(m)`` and ``TTL(m)`` on an entire non-frozen map or set column are **not** supported —
+since each element may have a different timestamp or TTL, there is no single meaningful value to return.
+Only ``WRITETIME(m[key])`` and ``TTL(m[key])`` (for a specific map key) or ``WRITETIME(s[element])``
+and ``TTL(s[element])`` (for a specific set element) are allowed.
+
+**Using** ``WRITETIME`` **and** ``TTL`` **on user-defined type fields**
+
+For a non-frozen user-defined type (UDT) column, each field is stored as an independent cell and may have its own
+write timestamp and TTL. You can retrieve the per-field timestamp or TTL using dot notation::
+
+ CREATE TYPE address (street text, city text);
+ CREATE TABLE person (pk int PRIMARY KEY, addr address);
+
+ -- Write two fields at different timestamps
+ UPDATE person USING TIMESTAMP 1000000 SET addr.street = '123 Main St' WHERE pk = 1;
+ UPDATE person USING TIMESTAMP 2000000 SET addr.city = 'Springfield' WHERE pk = 1;
+
+ -- WRITETIME(udt_column.field) returns the write timestamp of that specific UDT field
+ SELECT WRITETIME(addr.street), WRITETIME(addr.city) FROM person WHERE pk = 1;
+ -- Returns: 1000000 | 2000000
+
+ -- TTL(udt_column.field) returns the remaining TTL of that specific UDT field
+ UPDATE person USING TTL 3600 SET addr.street = 'Oak Ave' WHERE pk = 1;
+ SELECT TTL(addr.street) FROM person WHERE pk = 1;
+ -- Returns the remaining TTL in seconds for addr.street
.. _where-clause:
diff --git a/docs/cql/time-to-live.rst b/docs/cql/time-to-live.rst
index f170723aba..02e230ff8c 100644
--- a/docs/cql/time-to-live.rst
+++ b/docs/cql/time-to-live.rst
@@ -97,7 +97,33 @@ The ``gc_grace_seconds`` parameter is defined :ref:`here ` CQL Reference.
+You can set the TTL on a per element basis for collections.
+
+See for example the :ref:`Maps ` CQL Reference for map collections.
+For a non-frozen map or set column, each element is stored independently and can have its own TTL. You can query the
+remaining TTL for a specific map element using ``TTL(map_column[key])`` or for a specific set element using
+``TTL(set_column[element])``:
+
+.. code-block:: cql
+
+ CREATE TABLE t (pk int PRIMARY KEY, m map, s set);
+ INSERT INTO t (pk, m, s) VALUES (1, {1: 10}, {100}) USING TTL 3600;
+ UPDATE t USING TTL 7200 SET m = m + {2: 20}, s = s + {200} WHERE pk = 1;
+
+ -- Returns the remaining TTL for each map element independently
+ SELECT TTL(m[1]), TTL(m[2]) FROM t WHERE pk = 1;
+
+ -- Returns the remaining TTL for each set element independently
+ SELECT TTL(s[100]), TTL(s[200]) FROM t WHERE pk = 1;
+
+Similarly, you can retrieve the write timestamp of a specific map element using ``WRITETIME(map_column[key])``
+or of a specific set element using ``WRITETIME(set_column[element])``.
+
+For a non-frozen user-defined type (UDT) column, each field is also stored independently and can have its own TTL.
+You can query the remaining TTL or write timestamp of a specific field using dot notation:
+``TTL(udt_column.field)`` and ``WRITETIME(udt_column.field)``.
+
+See the :ref:`WRITETIME and TTL function ` section for details.
Notes
^^^^^