Skip to content

Commit 28b94cc

Browse files
committed
Reduce dependencies of catalog-protos
The mz-catalog-protos crate has a large number of dependencies that aren't strictly needed. Sepcifically, it transitively depends on timely and the likes, which is not ideal for a crate that is supposed to maintain the catalog. This change aims at extracting types that have a representation in the catalog into a separate crate that does not have any odd dependency. Signed-off-by: Moritz Hoffmann <[email protected]>
1 parent d4ed600 commit 28b94cc

File tree

17 files changed

+249
-207
lines changed

17 files changed

+249
-207
lines changed

Cargo.lock

Lines changed: 14 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ members = [
1717
"src/catalog",
1818
"src/catalog-debug",
1919
"src/catalog-protos",
20+
"src/catalog-types",
2021
"src/ccsr",
2122
"src/cloud-api",
2223
"src/cloud-provider",

src/catalog-protos/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ workspace = true
1010

1111
[dependencies]
1212
mz-audit-log = { path = "../audit-log" }
13-
mz-compute-types = { path = "../compute-types" }
14-
mz-controller-types = { path = "../controller-types" }
13+
mz-catalog-types = { path = "../catalog-types" }
1514
mz-proto = { path = "../proto" }
1615
mz-repr = { path = "../repr" }
1716
mz-sql = { path = "../sql" }
18-
mz-storage-types = { path = "../storage-types" }
1917
paste = "1.0.11"
2018
proptest = { version = "1.7.0", default-features = false, features = ["std"] }
2119
proptest-derive = { version = "0.5.1", features = ["boxed_union"] }

src/catalog-protos/src/serialization.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
1616
use std::time::Duration;
1717

18-
use mz_compute_types::config::ComputeReplicaLogging;
19-
use mz_controller_types::ReplicaId;
18+
use mz_catalog_types::cluster::ReplicaId;
19+
use mz_catalog_types::cluster::StorageInstanceId;
20+
use mz_catalog_types::compute::ComputeReplicaLogging;
2021
use mz_proto::{IntoRustIfSome, ProtoMapEntry, ProtoType, RustType, TryFromProtoError};
2122
use mz_repr::adt::mz_acl_item::{AclMode, MzAclItem};
2223
use mz_repr::network_policy_id::NetworkPolicyId;
2324
use mz_repr::role_id::RoleId;
24-
use mz_repr::{CatalogItemId, GlobalId, RelationVersion, Timestamp};
25+
use mz_repr::{CatalogItemId, GlobalId, RelationVersion};
2526
use mz_sql::catalog::{CatalogItemType, ObjectType, RoleAttributes, RoleMembership, RoleVars};
2627
use mz_sql::names::{
2728
CommentObjectId, DatabaseId, ResolvedDatabaseSpecifier, SchemaId, SchemaSpecifier,
@@ -31,7 +32,6 @@ use mz_sql::plan::{
3132
PolicyAddress,
3233
};
3334
use mz_sql::session::vars::OwnedVarInput;
34-
use mz_storage_types::instances::StorageInstanceId;
3535

3636
use crate::objects::Empty;
3737

@@ -566,18 +566,6 @@ impl RustType<crate::objects::EpochMillis> for u64 {
566566
}
567567
}
568568

569-
impl RustType<crate::objects::Timestamp> for Timestamp {
570-
fn into_proto(&self) -> crate::objects::Timestamp {
571-
crate::objects::Timestamp {
572-
internal: self.into(),
573-
}
574-
}
575-
576-
fn from_proto(proto: crate::objects::Timestamp) -> Result<Self, TryFromProtoError> {
577-
Ok(Timestamp::new(proto.internal))
578-
}
579-
}
580-
581569
impl RustType<crate::objects::CatalogItemId> for CatalogItemId {
582570
fn into_proto(&self) -> crate::objects::CatalogItemId {
583571
crate::objects::CatalogItemId {

src/catalog-types/src/cluster.rs

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
// Copyright Materialize, Inc. and contributors. All rights reserved.
2+
//
3+
// Use of this software is governed by the Business Source License
4+
// included in the LICENSE file.
5+
//
6+
// As of the Change Date specified in that file, in accordance with
7+
// the Business Source License, use of this software will be governed
8+
// by the Apache License, Version 2.0.
9+
10+
//! Types related to clusters.
11+
12+
use std::fmt;
13+
use std::str::FromStr;
14+
15+
use serde::{Deserialize, Serialize};
16+
use tracing::error;
17+
18+
/// Identifier of a storage instance.
19+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
20+
pub enum StorageInstanceId {
21+
/// A system storage instance.
22+
System(u64),
23+
/// A user storage instance.
24+
User(u64),
25+
}
26+
27+
impl StorageInstanceId {
28+
/// Creates a new `StorageInstanceId` in the system namespace. The top 16 bits of `id` must be
29+
/// 0, because this ID is packed into 48 bits of
30+
/// [`mz_repr::GlobalId::IntrospectionSourceIndex`].
31+
pub fn system(id: u64) -> Option<Self> {
32+
Self::new(id, Self::System)
33+
}
34+
35+
/// Creates a new `StorageInstanceId` in the user namespace. The top 16 bits of `id` must be
36+
/// 0, because this ID is packed into 48 bits of
37+
/// [`mz_repr::GlobalId::IntrospectionSourceIndex`].
38+
pub fn user(id: u64) -> Option<Self> {
39+
Self::new(id, Self::User)
40+
}
41+
42+
fn new(id: u64, variant: fn(u64) -> Self) -> Option<Self> {
43+
const MASK: u64 = 0xFFFF << 48;
44+
const WARN_MASK: u64 = 1 << 47;
45+
if MASK & id == 0 {
46+
if WARN_MASK & id != 0 {
47+
error!("{WARN_MASK} or more `StorageInstanceId`s allocated, we will run out soon");
48+
}
49+
Some(variant(id))
50+
} else {
51+
None
52+
}
53+
}
54+
55+
/// Extract the inner u64 ID.
56+
pub fn inner_id(&self) -> u64 {
57+
match self {
58+
StorageInstanceId::System(id) | StorageInstanceId::User(id) => *id,
59+
}
60+
}
61+
62+
/// Returns true if this represents a user object.
63+
pub fn is_user(&self) -> bool {
64+
matches!(self, Self::User(_))
65+
}
66+
67+
/// Returns true if this represents a system object.
68+
pub fn is_system(&self) -> bool {
69+
matches!(self, Self::System(_))
70+
}
71+
}
72+
73+
impl FromStr for StorageInstanceId {
74+
type Err = IdParseError<Cluster>;
75+
76+
fn from_str(s: &str) -> Result<Self, Self::Err> {
77+
if s.len() < 2 {
78+
return Err(s.into());
79+
}
80+
let val: u64 = s[1..].parse()?;
81+
match s.chars().next().unwrap() {
82+
's' => Ok(Self::System(val)),
83+
'u' => Ok(Self::User(val)),
84+
_ => Err(s.into()),
85+
}
86+
}
87+
}
88+
89+
/// An error parsing a `StorageInstanceId`.
90+
#[derive(Debug)]
91+
pub struct IdParseError<V> {
92+
reason: String,
93+
_marker: std::marker::PhantomData<V>,
94+
}
95+
96+
impl<V: fmt::Debug> std::error::Error for IdParseError<V> {}
97+
98+
impl<V> fmt::Display for IdParseError<V> {
99+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100+
write!(f, "couldn't parse id {}", self.reason)
101+
}
102+
}
103+
104+
impl<V> From<&str> for IdParseError<V> {
105+
fn from(reason: &str) -> Self {
106+
reason.to_string().into()
107+
}
108+
}
109+
110+
impl<V> From<std::num::ParseIntError> for IdParseError<V> {
111+
fn from(error: std::num::ParseIntError) -> Self {
112+
error.to_string().into()
113+
}
114+
}
115+
116+
impl<V> From<String> for IdParseError<V> {
117+
fn from(reason: String) -> Self {
118+
Self {
119+
reason,
120+
_marker: std::marker::PhantomData,
121+
}
122+
}
123+
}
124+
125+
impl fmt::Display for StorageInstanceId {
126+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
127+
match self {
128+
Self::System(id) => write!(f, "s{}", id),
129+
Self::User(id) => write!(f, "u{}", id),
130+
}
131+
}
132+
}
133+
134+
/// Identifier of a replica.
135+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
136+
pub enum ReplicaId {
137+
/// A user replica.
138+
User(u64),
139+
/// A system replica.
140+
System(u64),
141+
}
142+
143+
impl ReplicaId {
144+
/// Return the inner numeric ID value.
145+
pub fn inner_id(&self) -> u64 {
146+
match self {
147+
ReplicaId::User(id) => *id,
148+
ReplicaId::System(id) => *id,
149+
}
150+
}
151+
152+
/// Whether this value identifies a user replica.
153+
pub fn is_user(&self) -> bool {
154+
matches!(self, Self::User(_))
155+
}
156+
157+
/// Whether this value identifies a system replica.
158+
pub fn is_system(&self) -> bool {
159+
matches!(self, Self::System(_))
160+
}
161+
}
162+
163+
impl fmt::Display for ReplicaId {
164+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165+
match self {
166+
Self::User(id) => write!(f, "u{}", id),
167+
Self::System(id) => write!(f, "s{}", id),
168+
}
169+
}
170+
}
171+
172+
impl FromStr for ReplicaId {
173+
type Err = IdParseError<Replica>;
174+
175+
fn from_str(s: &str) -> Result<Self, Self::Err> {
176+
let first = s.chars().next();
177+
let rest = s.get(1..);
178+
if let (Some(prefix), Some(num)) = (first, rest) {
179+
let id = num.parse()?;
180+
match prefix {
181+
'u' => return Ok(Self::User(id)),
182+
's' => return Ok(Self::System(id)),
183+
_ => (),
184+
}
185+
}
186+
187+
Err(s.into())
188+
}
189+
}
190+
191+
/// A marker type for replica ID parse errors.
192+
#[derive(Debug)]
193+
pub struct Replica;
194+
impl fmt::Display for Replica {
195+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196+
write!(f, "replica")
197+
}
198+
}
199+
200+
/// A marker type for cluster ID parse errors.
201+
#[derive(Debug)]
202+
pub struct Cluster;
203+
impl fmt::Display for Cluster {
204+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
205+
write!(f, "cluster")
206+
}
207+
}
File renamed without changes.

src/cluster-client/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ publish = false
1010
workspace = true
1111

1212
[dependencies]
13-
anyhow = "1.0.100"
13+
mz-catalog-types = { path = "../catalog-types" }
1414
mz-ore = { path = "../ore", features = ["tracing"] }
1515
mz-repr = { path = "../repr" }
1616
prometheus = { version = "0.14.0", default-features = false }

0 commit comments

Comments
 (0)