Skip to content

Commit a185262

Browse files
committed
switch to repr types in typecheck transform
1 parent 289cf5b commit a185262

File tree

7 files changed

+344
-202
lines changed

7 files changed

+344
-202
lines changed

src/repr/src/explain.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use crate::explain::dot::{DisplayDot, dot_string};
4545
use crate::explain::json::{DisplayJson, json_string};
4646
use crate::explain::text::{DisplayText, text_string};
4747
use crate::optimize::OptimizerFeatureOverrides;
48-
use crate::{GlobalId, SqlColumnType, SqlScalarType};
48+
use crate::{GlobalId, ReprColumnType, ReprScalarType, SqlColumnType, SqlScalarType};
4949

5050
pub mod dot;
5151
pub mod json;
@@ -444,6 +444,12 @@ pub trait ExprHumanizer: fmt::Debug {
444444
/// compatibility is more important.
445445
fn humanize_scalar_type(&self, ty: &SqlScalarType, postgres_compat: bool) -> String;
446446

447+
/// Returns a human-readable name for the specified scalar type.
448+
/// Calls `humanize_scalar_type` with the `SqlScalarType` representation of the specified type.
449+
fn humanize_scalar_type_repr(&self, typ: &ReprScalarType, postgres_compat: bool) -> String {
450+
self.humanize_scalar_type(&SqlScalarType::from_repr(typ), postgres_compat)
451+
}
452+
447453
/// Returns a human-readable name for the specified column type.
448454
/// Used in, e.g., EXPLAIN and error msgs, in which case exact Postgres compatibility is less
449455
/// important than showing as much detail as possible. Also used in `pg_typeof`, where Postgres
@@ -456,6 +462,12 @@ pub trait ExprHumanizer: fmt::Debug {
456462
)
457463
}
458464

465+
/// Returns a human-readable name for the specified column type.
466+
/// Calls `humanize_column_type` with the `SqlColumnType` representation of the specified type.
467+
fn humanize_column_type_repr(&self, typ: &ReprColumnType, postgres_compat: bool) -> String {
468+
self.humanize_column_type(&SqlColumnType::from_repr(typ), postgres_compat)
469+
}
470+
459471
/// Returns a vector of column names for the relation identified by `id`.
460472
fn column_names_for_id(&self, id: GlobalId) -> Option<Vec<String>>;
461473

src/repr/src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ pub use crate::global_id::GlobalId;
5454
pub use crate::relation::{
5555
ColumnIndex, ColumnName, NotNullViolation, PropRelationDescDiff, ProtoColumnName,
5656
ProtoColumnType, ProtoRelationDesc, ProtoRelationType, RelationDesc, RelationDescBuilder,
57-
RelationVersion, RelationVersionSelector, ReprColumnType, SqlColumnType, SqlRelationType,
58-
UNKNOWN_COLUMN_NAME, VersionedRelationDesc, arb_relation_desc_diff,
57+
RelationVersion, RelationVersionSelector, ReprColumnType, ReprRelationType, SqlColumnType,
58+
SqlRelationType, UNKNOWN_COLUMN_NAME, VersionedRelationDesc, arb_relation_desc_diff,
5959
arb_relation_desc_projection, arb_row_for_relation,
6060
};
6161
pub use crate::row::encode::{RowColumnarDecoder, RowColumnarEncoder, preserves_order};
@@ -66,7 +66,7 @@ pub use crate::row::{
6666
};
6767
pub use crate::scalar::{
6868
ArrayRustType, AsColumnType, Datum, DatumType, PropArray, PropDatum, PropDict, PropList,
69-
ProtoScalarType, ReprScalarType, ScalarBaseType, SqlScalarType, arb_datum,
70-
arb_datum_for_column, arb_datum_for_scalar, arb_range_type,
69+
ProtoScalarType, ReprScalarBaseType, ReprScalarType, SqlScalarBaseType, SqlScalarType,
70+
arb_datum, arb_datum_for_column, arb_datum_for_scalar, arb_range_type,
7171
};
7272
pub use crate::timestamp::{Timestamp, TimestampManipulation};

src/repr/src/relation.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,94 @@ impl RustType<ProtoKey> for Vec<usize> {
259259
}
260260
}
261261

262+
/// The type of a relation.
263+
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
264+
pub struct ReprRelationType {
265+
/// The type for each column, in order.
266+
pub column_types: Vec<ReprColumnType>,
267+
/// Sets of indices that are "keys" for the collection.
268+
///
269+
/// Each element in this list is a set of column indices, each with the
270+
/// property that the collection contains at most one record with each
271+
/// distinct set of values for each column. Alternately, for a specific set
272+
/// of values assigned to the these columns there is at most one record.
273+
///
274+
/// A collection can contain multiple sets of keys, although it is common to
275+
/// have either zero or one sets of key indices.
276+
#[serde(default)]
277+
pub keys: Vec<Vec<usize>>,
278+
}
279+
280+
impl ReprRelationType {
281+
/// Constructs a `ReprRelationType` representing the relation with no columns and
282+
/// no keys.
283+
pub fn empty() -> Self {
284+
ReprRelationType::new(vec![])
285+
}
286+
287+
/// Constructs a new `ReprRelationType` from specified column types.
288+
///
289+
/// The `ReprRelationType` will have no keys.
290+
pub fn new(column_types: Vec<ReprColumnType>) -> Self {
291+
ReprRelationType {
292+
column_types,
293+
keys: Vec::new(),
294+
}
295+
}
296+
297+
/// Adds a new key for the relation.
298+
pub fn with_key(mut self, mut indices: Vec<usize>) -> Self {
299+
indices.sort_unstable();
300+
if !self.keys.contains(&indices) {
301+
self.keys.push(indices);
302+
}
303+
self
304+
}
305+
306+
pub fn with_keys(mut self, keys: Vec<Vec<usize>>) -> Self {
307+
for key in keys {
308+
self = self.with_key(key)
309+
}
310+
self
311+
}
312+
313+
/// Computes the number of columns in the relation.
314+
pub fn arity(&self) -> usize {
315+
self.column_types.len()
316+
}
317+
318+
/// Gets the index of the columns used when creating a default index.
319+
pub fn default_key(&self) -> Vec<usize> {
320+
if let Some(key) = self.keys.first() {
321+
if key.is_empty() {
322+
(0..self.column_types.len()).collect()
323+
} else {
324+
key.clone()
325+
}
326+
} else {
327+
(0..self.column_types.len()).collect()
328+
}
329+
}
330+
331+
/// Returns all the column types in order, for this relation.
332+
pub fn columns(&self) -> &[ReprColumnType] {
333+
&self.column_types
334+
}
335+
}
336+
337+
impl From<&SqlRelationType> for ReprRelationType {
338+
fn from(sql_relation_type: &SqlRelationType) -> Self {
339+
ReprRelationType {
340+
column_types: sql_relation_type
341+
.column_types
342+
.iter()
343+
.map(ReprColumnType::from)
344+
.collect(),
345+
keys: sql_relation_type.keys.clone(),
346+
}
347+
}
348+
}
349+
262350
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash, MzReflect)]
263351
pub struct ReprColumnType {
264352
/// The underlying representation scalar type (e.g., Int32 or String) of this column.

src/repr/src/scalar.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,7 +1591,7 @@ impl fmt::Display for Datum<'_> {
15911591
#[derive(
15921592
Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash, EnumKind, MzReflect,
15931593
)]
1594-
#[enum_kind(ScalarBaseType, derive(PartialOrd, Ord, Hash))]
1594+
#[enum_kind(SqlScalarBaseType, derive(PartialOrd, Ord, Hash))]
15951595
pub enum SqlScalarType {
15961596
/// The type of [`Datum::True`] and [`Datum::False`].
15971597
Bool,
@@ -3212,7 +3212,7 @@ impl SqlScalarType {
32123212
&& a.1.scalar_type.eq_inner(&b.1.scalar_type, structure_only)
32133213
})
32143214
}
3215-
(s, o) => ScalarBaseType::from(s) == ScalarBaseType::from(o),
3215+
(s, o) => SqlScalarBaseType::from(s) == SqlScalarBaseType::from(o),
32163216
}
32173217
}
32183218

@@ -4068,7 +4068,10 @@ impl Arbitrary for ReprScalarType {
40684068
/// There is a direct correspondence between `Datum` variants and `ReprScalarType`
40694069
/// variants: every `Datum` variant corresponds to exactly one `ReprScalarType` variant
40704070
/// (with an exception for `Datum::Array`, which could be both an `Int2Vector` and an `Array`).
4071-
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash, MzReflect)]
4071+
#[derive(
4072+
Clone, Debug, EnumKind, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd, Hash, MzReflect,
4073+
)]
4074+
#[enum_kind(ReprScalarBaseType, derive(PartialOrd, Ord, Hash))]
40724075
pub enum ReprScalarType {
40734076
Bool,
40744077
Int16,

src/sql/src/func.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use mz_ore::collections::CollectionExt;
2121
use mz_ore::str::StrExt;
2222
use mz_pgrepr::oid;
2323
use mz_repr::role_id::RoleId;
24-
use mz_repr::{ColumnName, Datum, ScalarBaseType, SqlRelationType, SqlScalarType};
24+
use mz_repr::{ColumnName, Datum, SqlRelationType, SqlScalarBaseType, SqlScalarType};
2525

2626
use crate::ast::{SelectStatement, Statement};
2727
use crate::catalog::{CatalogType, TypeCategory, TypeReference};
@@ -856,9 +856,9 @@ impl From<SqlScalarType> for ParamType {
856856
}
857857
}
858858

859-
impl From<ScalarBaseType> for ParamType {
860-
fn from(s: ScalarBaseType) -> ParamType {
861-
use ScalarBaseType::*;
859+
impl From<SqlScalarBaseType> for ParamType {
860+
fn from(s: SqlScalarBaseType) -> ParamType {
861+
use SqlScalarBaseType::*;
862862
let s = match s {
863863
Array | List | Map | Record | Range => {
864864
panic!("use polymorphic parameters rather than {:?}", s);
@@ -938,8 +938,8 @@ impl From<ParamType> for ReturnType {
938938
}
939939
}
940940

941-
impl From<ScalarBaseType> for ReturnType {
942-
fn from(s: ScalarBaseType) -> ReturnType {
941+
impl From<SqlScalarBaseType> for ReturnType {
942+
fn from(s: SqlScalarBaseType) -> ReturnType {
943943
ParamType::from(s).into()
944944
}
945945
}
@@ -1802,7 +1802,7 @@ macro_rules! privilege_fn {
18021802
/// Correlates a built-in function name to its implementations.
18031803
pub static PG_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
18041804
use ParamType::*;
1805-
use ScalarBaseType::*;
1805+
use SqlScalarBaseType::*;
18061806
let mut builtins = builtins! {
18071807
// Literal OIDs collected from PG 13 using a version of this query
18081808
// ```sql
@@ -3537,7 +3537,7 @@ pub static INFORMATION_SCHEMA_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> =
35373537

35383538
pub static MZ_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
35393539
use ParamType::*;
3540-
use ScalarBaseType::*;
3540+
use SqlScalarBaseType::*;
35413541
builtins! {
35423542
"constant_time_eq" => Scalar {
35433543
params!(Bytes, Bytes) => BinaryFunc::from(func::ConstantTimeEqBytes) => Bool, oid::FUNC_CONSTANT_TIME_EQ_BYTES_OID;
@@ -3952,7 +3952,7 @@ pub static MZ_CATALOG_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLoc
39523952

39533953
pub static MZ_INTERNAL_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
39543954
use ParamType::*;
3955-
use ScalarBaseType::*;
3955+
use SqlScalarBaseType::*;
39563956
builtins! {
39573957
"aclitem_grantor" => Scalar {
39583958
params!(AclItem) => UnaryFunc::AclItemGrantor(func::AclItemGrantor) => Oid, oid::FUNC_ACL_ITEM_GRANTOR_OID;
@@ -4339,7 +4339,7 @@ pub static MZ_INTERNAL_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLo
43394339

43404340
pub static MZ_UNSAFE_BUILTINS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
43414341
use ParamType::*;
4342-
use ScalarBaseType::*;
4342+
use SqlScalarBaseType::*;
43434343
builtins! {
43444344
"mz_all" => Aggregate {
43454345
params!(Any) => AggregateFunc::All => Bool, oid::FUNC_MZ_ALL_OID;
@@ -4459,7 +4459,7 @@ fn array_to_string(
44594459
pub static OP_IMPLS: LazyLock<BTreeMap<&'static str, Func>> = LazyLock::new(|| {
44604460
use BinaryFunc as BF;
44614461
use ParamType::*;
4462-
use ScalarBaseType::*;
4462+
use SqlScalarBaseType::*;
44634463
builtins! {
44644464
// Literal OIDs collected from PG 13 using a version of this query
44654465
// ```sql

src/sql/src/plan/typeconv.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ use dynfmt::{Format, SimpleCurlyFormat};
1818
use itertools::Itertools;
1919
use mz_expr::func::{CastArrayToJsonb, CastListToJsonb};
2020
use mz_expr::{VariadicFunc, func};
21-
use mz_repr::{ColumnName, Datum, ScalarBaseType, SqlColumnType, SqlRelationType, SqlScalarType};
21+
use mz_repr::{
22+
ColumnName, Datum, SqlColumnType, SqlRelationType, SqlScalarBaseType, SqlScalarType,
23+
};
2224

2325
use crate::catalog::TypeCategory;
2426
use crate::plan::error::PlanError;
@@ -294,9 +296,9 @@ macro_rules! casts(
294296
}};
295297
);
296298

297-
static VALID_CASTS: LazyLock<BTreeMap<(ScalarBaseType, ScalarBaseType), CastImpl>> = LazyLock::new(
298-
|| {
299-
use ScalarBaseType::*;
299+
static VALID_CASTS: LazyLock<BTreeMap<(SqlScalarBaseType, SqlScalarBaseType), CastImpl>> =
300+
LazyLock::new(|| {
301+
use SqlScalarBaseType::*;
300302
use UnaryFunc::*;
301303

302304
casts! {
@@ -865,8 +867,7 @@ static VALID_CASTS: LazyLock<BTreeMap<(ScalarBaseType, ScalarBaseType), CastImpl
865867
)
866868
)")
867869
}
868-
},
869-
);
870+
});
870871

871872
/// Get casts directly between two [`SqlScalarType`]s, with control over the
872873
/// allowed [`CastContext`].

0 commit comments

Comments
 (0)