diff --git a/src/query/fns/label.rs b/src/query/fns/label.rs
index 15b0e28d2323c5e22bae65d83ef08f0ea8daf786..6caa4bc0e37f66f638b71b0629ce08db2f8e52c2 100644
--- a/src/query/fns/label.rs
+++ b/src/query/fns/label.rs
@@ -7,6 +7,15 @@ use crate::query::{
     ops::Operable,
 };
 
+/// MetricsQL's label_set label manipulation query function
+#[inline]
+pub fn mql_label_set<'a>(
+    qry_expr: impl Operable + 'a,
+    label_value_pairs: &'a [&'a str],
+) -> QryFunc<impl Fn(&mut fmt::Formatter) -> fmt::Result + 'a> {
+    basic_label_fn("label_set", qry_expr, label_value_pairs)
+}
+
 /// MetricsQL's label_map query function
 pub fn mql_label_map<'a>(
     qry_expr: impl Operable + 'a,
@@ -111,4 +120,10 @@ mod tests {
             r#"sort_by_label_numeric_desc(metric,"label","label2")"#
         );
     }
+
+    #[test]
+    fn label_label_set() {
+        let qry = mql_label_set(Metric::new("metric"), &["label", "value"]).to_string();
+        assert_eq!(qry, r#"label_set(metric,"label","value")"#);
+    }
 }
diff --git a/src/query/fns/rollup.rs b/src/query/fns/rollup.rs
index 29b0f26c02b7329b9da1891b9d2b7f40b6713cc3..6565e8a065da152367f83caad79b4d7120779a89 100644
--- a/src/query/fns/rollup.rs
+++ b/src/query/fns/rollup.rs
@@ -4,6 +4,12 @@ use crate::query::ops::Operable;
 
 use super::{basic_fn, qry_fn, QryFunc};
 
+/// The timestamp rollup query function
+#[inline]
+pub fn timestamp(range_vec: impl Operable) -> QryFunc<impl Fn(&mut fmt::Formatter) -> fmt::Result> {
+    basic_fn("timestamp", range_vec)
+}
+
 /// The avg_over_time rollup query function
 #[inline]
 pub fn avg_over_time(
@@ -150,4 +156,10 @@ mod tests {
         let string = last_over_time(test_metric()).to_string();
         assert_eq!(string, "last_over_time(test_metric[15d])");
     }
+
+    #[test]
+    fn rollup_timestamp() {
+        let string = timestamp(test_metric()).to_string();
+        assert_eq!(string, "timestamp(test_metric[15d])");
+    }
 }
diff --git a/src/query/mod.rs b/src/query/mod.rs
index 8f463aa10c4423a3603f54f7bb3745973432a241..75bc237b7c23aca1d7b9a6d6d0b6304d85f6feb2 100644
--- a/src/query/mod.rs
+++ b/src/query/mod.rs
@@ -3,11 +3,12 @@
 //! [`Metric`] and [`Scalar`] are the basic types used for building queries.
 //! For building complex queries involving operators, see module [`ops`].
 
-use std::fmt::Display;
-
+use self::ops::Operable;
 use crate::seal::Sealed;
+use std::fmt::Display;
 
-use self::ops::Operable;
+#[cfg(feature = "metricsql")]
+use ops::modifiers::KeepNames;
 
 pub mod fns;
 pub mod ops;
@@ -450,6 +451,14 @@ pub trait QueryExt: Operable {
     {
         SubQry::new(self, dur)
     }
+
+    #[cfg(feature = "metricsql")]
+    fn keep_metric_names(self) -> KeepNames<Self>
+    where
+        Self: Sized,
+    {
+        KeepNames(self)
+    }
 }
 
 impl<T: Operable> QueryExt for T {}
diff --git a/src/query/ops/modifiers.rs b/src/query/ops/modifiers.rs
index 6cd40966957d70c4ad5228411d9f3cb52a8bb5f9..e9b2ae7f5585a40d2cf60db7759cdd19cab98db1 100644
--- a/src/query/ops/modifiers.rs
+++ b/src/query/ops/modifiers.rs
@@ -1,5 +1,9 @@
 use std::fmt::Display;
 
+use crate::{query::IntoQuery, seal::Sealed};
+
+use super::Operable;
+
 #[derive(Debug, Clone, Default)]
 pub(crate) struct Mod<'a, M> {
     mod_type: M,
@@ -114,3 +118,42 @@ impl Display for Mod<'_, AggrType> {
         Ok(())
     }
 }
+
+/// MetricsQL's `keep_metric_names` modifier
+///
+/// This modifier can only be applied using the `keep_metric_names` method made available by the [`QueryExt`](crate::query::QueryExt) trait.
+#[cfg(feature = "metricsql")]
+#[derive(Debug, Clone)]
+pub struct KeepNames<E: Operable>(pub(crate) E);
+
+#[cfg(feature = "metricsql")]
+impl<E: Operable> Display for KeepNames<E> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{exp} keep_metric_names", exp = self.0)
+    }
+}
+
+#[cfg(feature = "metricsql")]
+impl<E: Operable> Sealed for KeepNames<E> {}
+#[cfg(feature = "metricsql")]
+impl<E: Operable> Operable for KeepNames<E> {}
+
+#[cfg(feature = "metricsql")]
+impl<E: Operable> IntoQuery for KeepNames<E> {
+    type Target = String;
+    fn into_query(self) -> Self::Target {
+        self.to_string()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::query::{Metric, QueryExt};
+
+    #[cfg(feature = "metricsql")]
+    #[test]
+    fn keep_names() {
+        let qry = Metric::new("metric").keep_metric_names();
+        assert_eq!(qry.to_string(), "metric keep_metric_names");
+    }
+}
diff --git a/tests/fns.rs b/tests/fns.rs
index f63681a056bca6f17ebfaf0c1728b07992d38e4d..c81ceb02109f943bec4460ca983818de752862b6 100644
--- a/tests/fns.rs
+++ b/tests/fns.rs
@@ -83,7 +83,8 @@ rollup_tests!(
     stddev_over_time,
     stdvar_over_time,
     present_over_time,
-    last_over_time
+    last_over_time,
+    timestamp
 );
 
 #[tokio::test]
@@ -108,6 +109,7 @@ async fn mql_label_map() {
 
 #[cfg(feature = "metricsql")]
 label_tests!(
+    mql_label_set,
     mql_sort_by_label,
     mql_sort_by_label_desc,
     mql_sort_by_label_numeric,
diff --git a/tests/operators.rs b/tests/operators.rs
index a27ce155e8ed9b0822264b2a84d99a1a18b3d825..9813aaa2df25331951285a0a2a7042b0934e890d 100644
--- a/tests/operators.rs
+++ b/tests/operators.rs
@@ -1,6 +1,6 @@
 use mquery::query::{
     ops::{Arithmetic, Comparison, Logical},
-    Metric, Scalar,
+    Metric, QueryExt, Scalar,
 };
 
 mod utils;
@@ -89,3 +89,12 @@ async fn logical_set() {
         .unless(Metric::new("fourth_metric"));
     utils::send_query(query).await.unwrap();
 }
+
+#[cfg(feature = "metricsql")]
+#[tokio::test]
+async fn keep_metric_names_mod() {
+    let query = Metric::new("metric")
+        .add(Metric::new("metric2"))
+        .keep_metric_names();
+    utils::send_query(query).await.unwrap();
+}