MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / typecheck

Method typecheck

src/transform/src/typecheck.rs:884–1352  ·  view source on GitHub ↗

Returns the type of a relation expression or a type error. This function is careful to check validity, not just find out the type. It should be linear in the size of the AST. ??? should we also compute keys and return a `ReprRelationType`? ggevay: Checking keys would have the same problem as checking nullability: key inference is very heuristic (even more so than nullability inference), so it's

(
        &self,
        expr: &'a MirRelationExpr,
        ctx: &Context,
    )

Source from the content-addressed store, hash-verified

882 /// is very heuristic (even more so than nullability inference), so it's almost impossible to
883 /// reliably keep it stable across transformations.
884 pub fn typecheck<'a>(
885 &self,
886 expr: &'a MirRelationExpr,
887 ctx: &Context,
888 ) -> Result<Vec<ReprColumnType>, TypeError<'a>> {
889 use MirRelationExpr::*;
890
891 self.checked_recur(|tc| match expr {
892 Constant { typ, rows } => {
893 if let Ok(rows) = rows {
894 for (row, _id) in rows {
895 let datums = row.unpack();
896
897 let col_types = typ
898 .column_types
899 .iter()
900 .cloned()
901 .collect_vec();
902 row_difference_with_column_types(
903 expr, &datums, &col_types,
904 )?;
905
906 if self.disallow_dummy
907 && datums.iter().any(|d| d == &mz_repr::Datum::Dummy)
908 {
909 return Err(TypeError::DisallowedDummy {
910 source: expr,
911 });
912 }
913 }
914 }
915
916 Ok(typ.column_types.iter().cloned().collect_vec())
917 }
918 Get { typ, id, .. } => {
919 if let Id::Global(_global_id) = id {
920 if !ctx.contains_key(id) {
921 // TODO(mgree) pass QueryContext through to check these types
922 return Ok(typ.column_types.iter().cloned().collect_vec());
923 }
924 }
925
926 let ctx_typ = ctx.get(id).ok_or_else(|| TypeError::Unbound {
927 source: expr,
928 id: id.clone(),
929 typ: typ.clone(),
930 })?;
931
932 let column_types = typ.column_types.iter().cloned().collect_vec();
933
934 // covariant: the ascribed type must be a subtype of the actual type in the context
935 let diffs = relation_subtype_difference(&column_types, ctx_typ)
936 .into_iter()
937 .flat_map(|diff| diff.ignore_nullability())
938 .collect::<Vec<_>>();
939
940 if !diffs.is_empty() {
941 return Err(TypeError::MismatchColumns {

Callers 2

handle_typecheckFunction · 0.80

Calls 15

non_nullable_columnsFunction · 0.85
column_unionFunction · 0.85
checked_recurMethod · 0.80
anyMethod · 0.80
contains_keyMethod · 0.80
ignore_nullabilityMethod · 0.80
typecheck_scalarMethod · 0.80
enumerateMethod · 0.80
typecheck_aggregateMethod · 0.80

Tested by 1

handle_typecheckFunction · 0.64