diff --git a/oximeter/db/src/client.rs b/oximeter/db/src/client.rs index c2b7c820a8..2d563045f2 100644 --- a/oximeter/db/src/client.rs +++ b/oximeter/db/src/client.rs @@ -2634,4 +2634,45 @@ mod tests { db.cleanup().await.expect("Failed to cleanup ClickHouse server"); logctx.cleanup_successful(); } + + // Regression test for https://github.com/oxidecomputer/omicron/issues/4336. + // + // This tests that we can successfully query all extant datum types from the + // schema table. There may be no such values, but the query itself should + // succeed. + #[tokio::test] + async fn test_select_all_datum_types() { + use strum::IntoEnumIterator; + usdt::register_probes().unwrap(); + let logctx = test_setup_log("test_update_schema_cache_on_new_sample"); + let log = &logctx.log; + + // Let the OS assign a port and discover it after ClickHouse starts + let mut db = ClickHouseInstance::new_single_node(0) + .await + .expect("Failed to start ClickHouse"); + let address = SocketAddr::new("::1".parse().unwrap(), db.port()); + + let client = Client::new(address, &log); + client + .init_single_node_db() + .await + .expect("Failed to initialize timeseries database"); + + // Attempt to select all schema with each datum type. + for ty in oximeter::DatumType::iter() { + let sql = format!( + "SELECT COUNT() \ + FROM {}.timeseries_schema WHERE \ + datum_type = '{:?}'", + crate::DATABASE_NAME, + crate::model::DbDatumType::from(ty), + ); + let res = client.execute_with_body(sql).await.unwrap(); + let count = res.trim().parse::().unwrap(); + assert_eq!(count, 0); + } + db.cleanup().await.expect("Failed to cleanup ClickHouse server"); + logctx.cleanup_successful(); + } } diff --git a/oximeter/db/src/db-replicated-init.sql b/oximeter/db/src/db-replicated-init.sql index 7b756f4b0d..3b734c113d 100644 --- a/oximeter/db/src/db-replicated-init.sql +++ b/oximeter/db/src/db-replicated-init.sql @@ -652,7 +652,25 @@ CREATE TABLE IF NOT EXISTS oximeter.timeseries_schema ON CLUSTER oximeter_cluste 'CumulativeI64' = 6, 'CumulativeF64' = 7, 'HistogramI64' = 8, - 'HistogramF64' = 9 + 'HistogramF64' = 9, + 'I8' = 10, + 'U8' = 11, + 'I16' = 12, + 'U16' = 13, + 'I32' = 14, + 'U32' = 15, + 'U64' = 16, + 'F32' = 17, + 'CumulativeU64' = 18, + 'CumulativeF32' = 19, + 'HistogramI8' = 20, + 'HistogramU8' = 21, + 'HistogramI16' = 23, + 'HistogramU16' = 23, + 'HistogramI32' = 24, + 'HistogramU32' = 25, + 'HistogramU64' = 26, + 'HistogramF32' = 27 ), created DateTime64(9, 'UTC') ) diff --git a/oximeter/db/src/db-single-node-init.sql b/oximeter/db/src/db-single-node-init.sql index 1f648fd5d5..2fb5c36397 100644 --- a/oximeter/db/src/db-single-node-init.sql +++ b/oximeter/db/src/db-single-node-init.sql @@ -476,7 +476,25 @@ CREATE TABLE IF NOT EXISTS oximeter.timeseries_schema 'CumulativeI64' = 6, 'CumulativeF64' = 7, 'HistogramI64' = 8, - 'HistogramF64' = 9 + 'HistogramF64' = 9, + 'I8' = 10, + 'U8' = 11, + 'I16' = 12, + 'U16' = 13, + 'I32' = 14, + 'U32' = 15, + 'U64' = 16, + 'F32' = 17, + 'CumulativeU64' = 18, + 'CumulativeF32' = 19, + 'HistogramI8' = 20, + 'HistogramU8' = 21, + 'HistogramI16' = 22, + 'HistogramU16' = 23, + 'HistogramI32' = 24, + 'HistogramU32' = 25, + 'HistogramU64' = 26, + 'HistogramF32' = 27 ), created DateTime64(9, 'UTC') ) diff --git a/oximeter/db/src/model.rs b/oximeter/db/src/model.rs index 7f5b150b46..41c7ab9d24 100644 --- a/oximeter/db/src/model.rs +++ b/oximeter/db/src/model.rs @@ -42,7 +42,7 @@ use uuid::Uuid; /// /// TODO(#4271): The current implementation of versioning will wipe the metrics /// database if this number is incremented. -pub const OXIMETER_VERSION: u64 = 1; +pub const OXIMETER_VERSION: u64 = 2; // Wrapper type to represent a boolean in the database. // diff --git a/oximeter/oximeter/src/types.rs b/oximeter/oximeter/src/types.rs index d3f1b9e746..0cc3299ec4 100644 --- a/oximeter/oximeter/src/types.rs +++ b/oximeter/oximeter/src/types.rs @@ -275,6 +275,7 @@ pub struct Field { JsonSchema, Serialize, Deserialize, + strum::EnumIter, )] #[serde(rename_all = "snake_case")] pub enum DatumType {