1use common_base::regex_pattern::NAME_PATTERN_REG;
16pub use datafusion_common::ScalarValue;
17use once_cell::sync::OnceCell;
18use snafu::ensure;
19
20pub use crate::columnar_value::ColumnarValue;
21use crate::error::{InvalidColumnPrefixSnafu, Result};
22use crate::native_histogram::NATIVE_HISTOGRAM_FIELD;
23
24static GREPTIME_TIMESTAMP_CELL: OnceCell<String> = OnceCell::new();
26
27static GREPTIME_VALUE_CELL: OnceCell<String> = OnceCell::new();
29
30static GREPTIME_NATIVE_HISTOGRAM_CELL: OnceCell<String> = OnceCell::new();
32
33pub fn set_default_prefix(prefix: Option<&str>) -> Result<()> {
34 let stripped = prefix.map(|s| {
38 s.strip_prefix('"')
39 .and_then(|s| s.strip_suffix('"'))
40 .unwrap_or(s)
41 });
42
43 match stripped {
44 None => {
45 GREPTIME_TIMESTAMP_CELL.get_or_init(|| GREPTIME_TIMESTAMP.to_string());
47 GREPTIME_VALUE_CELL.get_or_init(|| GREPTIME_VALUE.to_string());
48 GREPTIME_NATIVE_HISTOGRAM_CELL.get_or_init(|| NATIVE_HISTOGRAM_FIELD.to_string());
49 }
50 Some(s) if s.trim().is_empty() => {
51 GREPTIME_TIMESTAMP_CELL.get_or_init(|| "timestamp".to_string());
53 GREPTIME_VALUE_CELL.get_or_init(|| "value".to_string());
54 GREPTIME_NATIVE_HISTOGRAM_CELL.get_or_init(|| "native_histogram".to_string());
55 }
56 Some(x) => {
57 ensure!(
58 NAME_PATTERN_REG.is_match(x),
59 InvalidColumnPrefixSnafu { prefix: x }
60 );
61 GREPTIME_TIMESTAMP_CELL.get_or_init(|| format!("{}_timestamp", x));
62 GREPTIME_VALUE_CELL.get_or_init(|| format!("{}_value", x));
63 GREPTIME_NATIVE_HISTOGRAM_CELL.get_or_init(|| format!("{}_native_histogram", x));
64 }
65 }
66 Ok(())
67}
68
69pub fn greptime_timestamp() -> &'static str {
72 GREPTIME_TIMESTAMP_CELL.get_or_init(|| GREPTIME_TIMESTAMP.to_string())
73}
74
75pub fn greptime_value() -> &'static str {
78 GREPTIME_VALUE_CELL.get_or_init(|| GREPTIME_VALUE.to_string())
79}
80
81#[inline]
84pub fn greptime_native_histogram() -> &'static str {
85 GREPTIME_NATIVE_HISTOGRAM_CELL
86 .get()
87 .map_or(NATIVE_HISTOGRAM_FIELD, String::as_str)
88}
89
90const GREPTIME_TIMESTAMP: &str = "greptime_timestamp";
92const GREPTIME_VALUE: &str = "greptime_value";
94pub const GREPTIME_COUNT: &str = "greptime_count";
96pub const OTLP_AGGREGATION_TEMPORALITY_LABEL: &str = "otlp_aggregation_temporality";
98pub const GREPTIME_TEMPORALITY_DELTA: &str = "delta";
100pub const GREPTIME_PHYSICAL_TABLE: &str = "greptime_physical_table";
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 #[test]
111 fn test_set_default_prefix_none() {
112 set_default_prefix(None).unwrap();
113 assert_eq!(greptime_timestamp(), "greptime_timestamp");
114 assert_eq!(greptime_value(), "greptime_value");
115 assert_eq!(greptime_native_histogram(), "greptime_native_histogram");
116 }
117
118 #[test]
119 fn test_set_default_prefix_empty_string() {
120 set_default_prefix(Some("")).unwrap();
121 assert_eq!(greptime_timestamp(), "timestamp");
122 assert_eq!(greptime_value(), "value");
123 assert_eq!(greptime_native_histogram(), "native_histogram");
124 }
125
126 #[test]
127 fn test_set_default_prefix_quoted_empty() {
128 set_default_prefix(Some("\"\"")).unwrap();
130 assert_eq!(greptime_timestamp(), "timestamp");
131 assert_eq!(greptime_value(), "value");
132 assert_eq!(greptime_native_histogram(), "native_histogram");
133 }
134
135 #[test]
136 fn test_set_default_prefix_custom() {
137 set_default_prefix(Some("mydb")).unwrap();
138 assert_eq!(greptime_timestamp(), "mydb_timestamp");
139 assert_eq!(greptime_value(), "mydb_value");
140 assert_eq!(greptime_native_histogram(), "mydb_native_histogram");
141 }
142
143 #[test]
144 fn test_set_default_prefix_invalid() {
145 assert!(set_default_prefix(Some("invalid prefix!")).is_err());
146 }
147}