Skip to content

Commit aad57cf

Browse files
authored
Remove redundant CAST to String for LowCardinality/Enum/UUID (#262)
2 parents f20b45f + d3b3f8b commit aad57cf

16 files changed

Lines changed: 97 additions & 57 deletions

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ libc = { version = "*", default-features = false }
3434
size = { version = "*", default-features = false, features = ["std"] }
3535
tempfile = { version = "*", default-features = false }
3636
url = { version = "*", default-features = false }
37+
# Must match clickhouse-rs (read UUID columns)
38+
uuid = { version = "*", default-features = false }
3739
humantime = { version = "*", default-features = false }
3840
backtrace = { version = "*", default-features = false, features = ["std"] }
3941
futures = { version = "*", default-features = false, features = ["std"] }

src/interpreter/clickhouse.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use chrono::{DateTime, Local};
1010
use chrono_tz::Tz;
1111
use clickhouse_rs::{
1212
Block, Options, Pool,
13-
types::{ColumnType, Complex, FromSql},
13+
types::{ColumnType, Complex, Enum8, Enum16, FromSql, SqlType},
1414
};
1515
use futures_util::StreamExt;
1616
use std::collections::HashMap;
@@ -23,6 +23,30 @@ use std::str::FromStr;
2323

2424
pub type Columns = Block<Complex>;
2525

26+
// clickhouse-rs reads an Enum column as its bare integer (FromSql drops the name mapping) and a
27+
// UUID as uuid::Uuid, so block.get::<String> fails on both; resolve the enum name from the Vec
28+
// carried by the column type and format the UUID. String and LowCardinality(String) fall through
29+
// to a plain String read (get coerces LC).
30+
pub fn column_as_string<K: ColumnType>(block: &Block<K>, row: usize, name: &str) -> Result<String> {
31+
let column = block
32+
.columns()
33+
.iter()
34+
.find(|c| c.name() == name)
35+
.ok_or_else(|| Error::msg(format!("Cannot get {name} column")))?;
36+
fn name_of<T: PartialEq + ToString>(values: &[(String, T)], v: T) -> String {
37+
values
38+
.iter()
39+
.find(|(_, k)| *k == v)
40+
.map_or_else(|| v.to_string(), |(name, _)| name.clone())
41+
}
42+
Ok(match column.sql_type() {
43+
SqlType::Enum8(values) => name_of(&values, block.get::<Enum8, _>(row, name)?.internal()),
44+
SqlType::Enum16(values) => name_of(&values, block.get::<Enum16, _>(row, name)?.internal()),
45+
SqlType::Uuid => block.get::<uuid::Uuid, _>(row, name)?.to_string(),
46+
_ => block.get::<String, _>(row, name)?,
47+
})
48+
}
49+
2650
pub struct ClickHouse {
2751
pub quirks: ClickHouseQuirks,
2852
// Server has use_shared_merge_tree_log_pipeline enabled (SharedMergeTree-backed system.*_log).
@@ -532,7 +556,7 @@ impl ClickHouse {
532556
elapsed / {q} AS elapsed,
533557
user,
534558
initial_user,
535-
''::String AS exception,
559+
'' AS exception,
536560
is_initial_query,
537561
is_cancelled,
538562
initial_query_id,
@@ -1029,9 +1053,9 @@ impl ClickHouse {
10291053
event_time,
10301054
event_time_microseconds,
10311055
thread_id,
1032-
level::String AS level,
1033-
logger_name::String AS logger_name,
1034-
query_id::String AS query_id,
1056+
level,
1057+
logger_name,
1058+
query_id,
10351059
message
10361060
FROM {}
10371061
WHERE
@@ -1458,7 +1482,7 @@ impl ClickHouse {
14581482
fromUnixTimestamp64Nano({start}) AS start_,
14591483
fromUnixTimestamp64Nano({end}) AS end_
14601484
SELECT
1461-
event_type::String AS event_type,
1485+
event_type,
14621486
event_time_microseconds,
14631487
duration_ms,
14641488
database,
@@ -1532,7 +1556,7 @@ impl ClickHouse {
15321556
{with}
15331557
SELECT
15341558
event_time_microseconds,
1535-
trace_type::String AS trace_type,
1559+
trace_type,
15361560
cityHash64(trace) AS stack_hash,
15371561
{host_expr} AS host_name
15381562
FROM {dbtable}
@@ -1602,8 +1626,8 @@ impl ClickHouse {
16021626
fromUnixTimestamp64Nano({end}) AS end_
16031627
SELECT
16041628
event_time_microseconds,
1605-
level::String AS level,
1606-
logger_name::String AS logger_name,
1629+
level,
1630+
logger_name,
16071631
message,
16081632
query_id,
16091633
{host_expr} AS host_name
@@ -1867,7 +1891,7 @@ impl ClickHouse {
18671891
database,
18681892
table,
18691893
format,
1870-
status::String AS status,
1894+
status,
18711895
bytes,
18721896
exception,
18731897
event_time_microseconds,
@@ -1934,7 +1958,7 @@ impl ClickHouse {
19341958
SELECT
19351959
file_name,
19361960
rows_processed,
1937-
status::String AS status,
1961+
status,
19381962
processing_start_time,
19391963
processing_end_time,
19401964
exception
@@ -1966,7 +1990,7 @@ impl ClickHouse {
19661990
table,
19671991
file_name,
19681992
rows_processed,
1969-
status::String AS status,
1993+
status,
19701994
processing_start_time,
19711995
processing_end_time,
19721996
exception
@@ -1997,7 +2021,7 @@ impl ClickHouse {
19972021
fromUnixTimestamp64Nano({start}) AS start_,
19982022
fromUnixTimestamp64Nano({end}) AS end_
19992023
SELECT
2000-
event_type::String AS event_type,
2024+
event_type,
20012025
query_id,
20022026
disk_name,
20032027
bucket,
@@ -2069,11 +2093,11 @@ impl ClickHouse {
20692093
fromUnixTimestamp64Nano({start}) AS start_,
20702094
fromUnixTimestamp64Nano({end}) AS end_
20712095
SELECT
2072-
type::String AS type,
2096+
type,
20732097
-- user/auth_type are Nullable
20742098
coalesce(user, '') AS user,
2075-
coalesce(auth_type::String, '') AS auth_type,
2076-
interface::String AS interface,
2099+
coalesce(auth_type, '') AS auth_type,
2100+
interface,
20772101
toString(client_address) AS client_address,
20782102
client_name,
20792103
failure_reason,
@@ -2106,7 +2130,7 @@ impl ClickHouse {
21062130
event_time,
21072131
session_id,
21082132
parent_path,
2109-
operation::String AS operation,
2133+
operation,
21102134
count::UInt64 AS count,
21112135
mapKeys(errors) AS error_names,
21122136
mapValues(errors) AS error_counts,

src/interpreter/perfetto.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::interpreter::Query;
2-
use crate::interpreter::clickhouse::{MetricLogRow, QueryMetricRow};
2+
use crate::interpreter::clickhouse::{MetricLogRow, QueryMetricRow, column_as_string};
33
use anyhow::Result;
44
use chrono::{DateTime, Local};
55
use chrono_tz::Tz;
@@ -614,7 +614,7 @@ impl PerfettoTraceBuilder {
614614
let process_uuid = self.process_track_uuid("Part Log");
615615

616616
for i in 0..columns.row_count() {
617-
let event_type: String = columns.get(i, "event_type").unwrap_or_default();
617+
let event_type: String = column_as_string(columns, i, "event_type").unwrap_or_default();
618618
let event_time: DateTime<Tz> = match columns.get(i, "event_time_microseconds") {
619619
Ok(v) => v,
620620
Err(e) => {
@@ -740,7 +740,7 @@ impl PerfettoTraceBuilder {
740740
};
741741

742742
for i in 0..columns.row_count() {
743-
let level: String = columns.get(i, "level").unwrap_or_default();
743+
let level: String = column_as_string(columns, i, "level").unwrap_or_default();
744744
let logger_name: String = columns.get(i, "logger_name").unwrap_or_default();
745745
let message: String = columns.get(i, "message").unwrap_or_default();
746746
let query_id: String = columns.get(i, "query_id").unwrap_or_default();
@@ -854,7 +854,7 @@ impl PerfettoTraceBuilder {
854854
let database: String = columns.get(i, "database").unwrap_or_default();
855855
let table: String = columns.get(i, "table").unwrap_or_default();
856856
let format: String = columns.get(i, "format").unwrap_or_default();
857-
let status: String = columns.get(i, "status").unwrap_or_default();
857+
let status: String = column_as_string(columns, i, "status").unwrap_or_default();
858858
let bytes: u64 = columns.get(i, "bytes").unwrap_or(0);
859859
let exception: String = columns.get(i, "exception").unwrap_or_default();
860860
let query_id: String = columns.get(i, "query_id").unwrap_or_default();
@@ -945,7 +945,7 @@ impl PerfettoTraceBuilder {
945945
for i in 0..columns.row_count() {
946946
let file_name: String = columns.get(i, "file_name").unwrap_or_default();
947947
let rows_processed: u64 = columns.get(i, "rows_processed").unwrap_or(0);
948-
let status: String = columns.get(i, "status").unwrap_or_default();
948+
let status: String = column_as_string(columns, i, "status").unwrap_or_default();
949949
let exception: String = columns.get(i, "exception").unwrap_or_default();
950950

951951
let start_ns: u64 = match columns.get::<DateTime<Tz>, _>(i, "processing_start_time") {
@@ -983,7 +983,7 @@ impl PerfettoTraceBuilder {
983983
let table: String = columns.get(i, "table").unwrap_or_default();
984984
let file_name: String = columns.get(i, "file_name").unwrap_or_default();
985985
let rows_processed: u64 = columns.get(i, "rows_processed").unwrap_or(0);
986-
let status: String = columns.get(i, "status").unwrap_or_default();
986+
let status: String = column_as_string(columns, i, "status").unwrap_or_default();
987987
let exception: String = columns.get(i, "exception").unwrap_or_default();
988988

989989
let start_ns: u64 = match columns.get::<DateTime<Tz>, _>(i, "processing_start_time") {
@@ -1020,7 +1020,7 @@ impl PerfettoTraceBuilder {
10201020
let process_uuid = self.process_track_uuid("Blob Storage");
10211021

10221022
for i in 0..columns.row_count() {
1023-
let event_type: String = columns.get(i, "event_type").unwrap_or_default();
1023+
let event_type: String = column_as_string(columns, i, "event_type").unwrap_or_default();
10241024
let query_id: String = columns.get(i, "query_id").unwrap_or_default();
10251025
let disk_name: String = columns.get(i, "disk_name").unwrap_or_default();
10261026
let bucket: String = columns.get(i, "bucket").unwrap_or_default();
@@ -1113,10 +1113,10 @@ impl PerfettoTraceBuilder {
11131113
let process_uuid = self.process_track_uuid("Sessions");
11141114

11151115
for i in 0..columns.row_count() {
1116-
let session_type: String = columns.get(i, "type").unwrap_or_default();
1116+
let session_type: String = column_as_string(columns, i, "type").unwrap_or_default();
11171117
let user: String = columns.get(i, "user").unwrap_or_default();
11181118
let auth_type: String = columns.get(i, "auth_type").unwrap_or_default();
1119-
let interface: String = columns.get(i, "interface").unwrap_or_default();
1119+
let interface: String = column_as_string(columns, i, "interface").unwrap_or_default();
11201120
let client_address: String = columns.get(i, "client_address").unwrap_or_default();
11211121
let client_name: String = columns.get(i, "client_name").unwrap_or_default();
11221122
let failure_reason: String = columns.get(i, "failure_reason").unwrap_or_default();
@@ -1159,7 +1159,7 @@ impl PerfettoTraceBuilder {
11591159
let process_uuid = self.process_track_uuid("ZooKeeper");
11601160

11611161
for i in 0..columns.row_count() {
1162-
let operation: String = columns.get(i, "operation").unwrap_or_default();
1162+
let operation: String = column_as_string(columns, i, "operation").unwrap_or_default();
11631163
let count: u64 = columns.get(i, "count").unwrap_or(0);
11641164
let average_latency: f64 = columns.get(i, "average_latency").unwrap_or(0.0);
11651165
let parent_path: String = columns.get(i, "parent_path").unwrap_or_default();
@@ -1310,7 +1310,7 @@ impl PerfettoTraceBuilder {
13101310
/// emitted by finalize_stack_traces() from build().
13111311
pub fn add_stack_samples<K: ColumnType>(&mut self, samples: &Block<K>) {
13121312
for i in 0..samples.row_count() {
1313-
let trace_type: String = samples.get(i, "trace_type").unwrap_or_default();
1313+
let trace_type: String = column_as_string(samples, i, "trace_type").unwrap_or_default();
13141314
let stack_hash: u64 = samples.get(i, "stack_hash").unwrap_or_default();
13151315
let host_name: String = samples.get(i, "host_name").unwrap_or_default();
13161316

src/view/providers/backups.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ impl ViewProvider for BackupsViewProvider {
2424
fn show(&self, siv: &mut Cursive, context: ContextArc) {
2525
let columns = vec![
2626
"name",
27-
"status::String status",
27+
"status",
2828
"error",
2929
"start_time",
3030
"end_time",

src/view/providers/dictionaries.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl ViewProvider for DictionariesViewProvider {
1919
fn show(&self, siv: &mut Cursive, context: ContextArc) {
2020
let columns = vec![
2121
"name",
22-
"status::String status",
22+
"status",
2323
"source",
2424
"bytes_allocated memory",
2525
"query_count queries",

src/view/providers/error_log.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ impl ViewProvider for ErrorLogViewProvider {
2626
}
2727

2828
let columns = vec![
29-
"error::String name",
29+
"error name",
3030
"any(code) code",
3131
"sum(value) total",
3232
"total bar",

src/view/providers/logger_names.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ impl ViewProvider for LoggerNamesViewProvider {
3838
let end = view_options.end;
3939

4040
let mut columns = vec![
41-
"logger_name::String logger_name",
41+
"logger_name",
4242
"count() count",
4343
"countIf(level = 'Fatal') fatal",
4444
"countIf(level = 'Critical') critical",

src/view/providers/merges.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fn get_columns(is_dialog: bool) -> Vec<&'static str> {
3838
"rows_written",
3939
"memory_usage memory",
4040
"now()-elapsed _create_time",
41-
"tables.uuid::String _table_uuid",
41+
"tables.uuid _table_uuid",
4242
]
4343
} else {
4444
vec![
@@ -54,7 +54,7 @@ fn get_columns(is_dialog: bool) -> Vec<&'static str> {
5454
"rows_written",
5555
"memory_usage memory",
5656
"now()-elapsed _create_time",
57-
"tables.uuid::String _table_uuid",
57+
"tables.uuid _table_uuid",
5858
]
5959
}
6060
}

src/view/providers/part_log.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,30 +123,30 @@ fn build_query(context: &ContextArc, filters: &FilterParams, is_dialog: bool) ->
123123

124124
let select_clause = if is_dialog {
125125
r#"event_time,
126-
event_type::String event_type,
126+
event_type,
127127
part_name,
128-
merge_algorithm::String merge_algorithm,
128+
merge_algorithm,
129129
part_type,
130130
rows,
131131
size_in_bytes,
132132
duration_ms,
133133
peak_memory_usage,
134134
exception,
135-
table_uuid::String _table_uuid"#
135+
table_uuid _table_uuid"#
136136
} else {
137137
r#"event_time,
138-
event_type::String event_type,
138+
event_type,
139139
database,
140140
table,
141141
part_name,
142-
merge_algorithm::String merge_algorithm,
142+
merge_algorithm,
143143
part_type,
144144
rows,
145145
size_in_bytes,
146146
duration_ms,
147147
peak_memory_usage,
148148
exception,
149-
table_uuid::String _table_uuid"#
149+
table_uuid _table_uuid"#
150150
};
151151

152152
format!(

0 commit comments

Comments
 (0)