(
&self,
desc: &RelationDesc,
)
| 927 | } |
| 928 | |
| 929 | pub fn relation_desc_into_table_defs( |
| 930 | &self, |
| 931 | desc: &RelationDesc, |
| 932 | ) -> Result<(Vec<ColumnDef<Aug>>, Vec<TableConstraint<Aug>>), PlanError> { |
| 933 | let mut columns = vec![]; |
| 934 | let mut null_cols = BTreeSet::new(); |
| 935 | for (column_name, column_type) in desc.iter() { |
| 936 | let name = Ident::new(column_name.as_str().to_owned())?; |
| 937 | |
| 938 | let ty = mz_pgrepr::Type::from(&column_type.scalar_type); |
| 939 | let data_type = self.resolve_type(ty)?; |
| 940 | |
| 941 | let options = if !column_type.nullable { |
| 942 | null_cols.insert(columns.len()); |
| 943 | vec![mz_sql_parser::ast::ColumnOptionDef { |
| 944 | name: None, |
| 945 | option: mz_sql_parser::ast::ColumnOption::NotNull, |
| 946 | }] |
| 947 | } else { |
| 948 | vec![] |
| 949 | }; |
| 950 | |
| 951 | columns.push(ColumnDef { |
| 952 | name, |
| 953 | data_type, |
| 954 | collation: None, |
| 955 | options, |
| 956 | }); |
| 957 | } |
| 958 | |
| 959 | let mut table_constraints = vec![]; |
| 960 | for key in desc.typ().keys.iter() { |
| 961 | let mut col_names = vec![]; |
| 962 | for col_idx in key { |
| 963 | if !null_cols.contains(col_idx) { |
| 964 | // Note that alternatively we could support NULL values in keys with `NULLS NOT |
| 965 | // DISTINCT` semantics, which treats `NULL` as a distinct value. |
| 966 | sql_bail!( |
| 967 | "[internal error] key columns must be NOT NULL when generating table constraints" |
| 968 | ); |
| 969 | } |
| 970 | col_names.push(columns[*col_idx].name.clone()); |
| 971 | } |
| 972 | table_constraints.push(TableConstraint::Unique { |
| 973 | name: None, |
| 974 | columns: col_names, |
| 975 | is_primary: false, |
| 976 | nulls_not_distinct: false, |
| 977 | }); |
| 978 | } |
| 979 | |
| 980 | Ok((columns, table_constraints)) |
| 981 | } |
| 982 | |
| 983 | pub fn get_owner_id(&self, id: &ObjectId) -> Option<RoleId> { |
| 984 | self.catalog.get_owner_id(id) |
no test coverage detected