Plans the RelationDesc for a source export (subsource or table) that has a defined list of columns and constraints.
(
scx: &StatementContext,
name: &UnresolvedItemName,
columns: &Vec<ColumnDef<Aug>>,
constraints: &Vec<TableConstraint<Aug>>,
)
| 1471 | /// Plans the RelationDesc for a source export (subsource or table) that has a defined list |
| 1472 | /// of columns and constraints. |
| 1473 | fn plan_source_export_desc( |
| 1474 | scx: &StatementContext, |
| 1475 | name: &UnresolvedItemName, |
| 1476 | columns: &Vec<ColumnDef<Aug>>, |
| 1477 | constraints: &Vec<TableConstraint<Aug>>, |
| 1478 | ) -> Result<RelationDesc, PlanError> { |
| 1479 | let names: Vec<_> = columns |
| 1480 | .iter() |
| 1481 | .map(|c| normalize::column_name(c.name.clone())) |
| 1482 | .collect(); |
| 1483 | |
| 1484 | if let Some(dup) = names.iter().duplicates().next() { |
| 1485 | sql_bail!("column {} specified more than once", dup.quoted()); |
| 1486 | } |
| 1487 | |
| 1488 | // Build initial relation type that handles declared data types |
| 1489 | // and NOT NULL constraints. |
| 1490 | let mut column_types = Vec::with_capacity(columns.len()); |
| 1491 | let mut keys = Vec::new(); |
| 1492 | |
| 1493 | for (i, c) in columns.into_iter().enumerate() { |
| 1494 | let aug_data_type = &c.data_type; |
| 1495 | let ty = query::scalar_type_from_sql(scx, aug_data_type)?; |
| 1496 | let mut nullable = true; |
| 1497 | for option in &c.options { |
| 1498 | match &option.option { |
| 1499 | ColumnOption::NotNull => nullable = false, |
| 1500 | ColumnOption::Default(_) => { |
| 1501 | bail_unsupported!("Source export with default value") |
| 1502 | } |
| 1503 | ColumnOption::Unique { is_primary } => { |
| 1504 | keys.push(vec![i]); |
| 1505 | if *is_primary { |
| 1506 | nullable = false; |
| 1507 | } |
| 1508 | } |
| 1509 | other => { |
| 1510 | bail_unsupported!(format!("Source export with column constraint: {}", other)) |
| 1511 | } |
| 1512 | } |
| 1513 | } |
| 1514 | column_types.push(ty.nullable(nullable)); |
| 1515 | } |
| 1516 | |
| 1517 | let mut seen_primary = false; |
| 1518 | 'c: for constraint in constraints { |
| 1519 | match constraint { |
| 1520 | TableConstraint::Unique { |
| 1521 | name: _, |
| 1522 | columns, |
| 1523 | is_primary, |
| 1524 | nulls_not_distinct, |
| 1525 | } => { |
| 1526 | if seen_primary && *is_primary { |
| 1527 | sql_bail!( |
| 1528 | "multiple primary keys for source export {} are not allowed", |
| 1529 | name.to_ast_string_stable() |
| 1530 | ); |