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

Method determine_key

src/sql/src/func.rs:1463–1524  ·  view source on GitHub ↗

Attempt to resolve all polymorphic types to a single "key" type. For `target_for_param_type` to be useful, this must have already been called.

(&mut self, ecx: &ExprContext)

Source from the content-addressed store, hash-verified

1461 /// `target_for_param_type` to be useful, this must have already been
1462 /// called.
1463 fn determine_key(&mut self, ecx: &ExprContext) -> bool {
1464 self.key = if !self.seen.iter().any(|v| v.is_coerced()) {
1465 match &self.compat {
1466 // No encountered param was polymorphic
1467 None => None,
1468 // Params were polymorphic, but we never received a known type.
1469 // This cannot be delegated to `guess_best_common_type`, which
1470 // will incorrectly guess string, which is incompatible with
1471 // `BestCommonList`, `BestCommonMap`.
1472 Some(t) => match t {
1473 PolymorphicCompatClass::BestCommonAny => Some(SqlScalarType::String),
1474 PolymorphicCompatClass::BestCommonList => Some(SqlScalarType::List {
1475 custom_id: None,
1476 element_type: Box::new(SqlScalarType::String),
1477 }),
1478 PolymorphicCompatClass::BestCommonMap => Some(SqlScalarType::Map {
1479 value_type: Box::new(SqlScalarType::String),
1480 custom_id: None,
1481 }),
1482 // Do not infer type.
1483 PolymorphicCompatClass::StructuralEq | PolymorphicCompatClass::Any => None,
1484 },
1485 }
1486 } else {
1487 // If we saw any polymorphic parameters, we must have determined the
1488 // compatibility type.
1489 let compat = self.compat.as_ref().unwrap();
1490
1491 let r = match compat {
1492 PolymorphicCompatClass::Any => {
1493 let mut s = self
1494 .seen
1495 .iter()
1496 .filter_map(|f| f.as_coerced().cloned())
1497 .collect::<Vec<_>>();
1498 let (candiate, remaining) =
1499 s.split_first().expect("have at least one non-None element");
1500 if remaining.iter().all(|r| r.base_eq(candiate)) {
1501 s.remove(0)
1502 } else {
1503 return false;
1504 }
1505 }
1506 _ => match typeconv::guess_best_common_type(ecx, &self.seen) {
1507 Ok(r) => r,
1508 Err(_) => return false,
1509 },
1510 };
1511
1512 // Ensure the best common type is compatible.
1513 for t in self.seen.iter() {
1514 if let CoercibleScalarType::Coerced(t) = t {
1515 if !compat.compatible(ecx, t, &r) {
1516 return false;
1517 }
1518 }
1519 }
1520 Some(r)

Callers 1

newMethod · 0.80

Calls 12

guess_best_common_typeFunction · 0.85
anyMethod · 0.80
is_coercedMethod · 0.80
unwrapMethod · 0.80
as_coercedMethod · 0.80
expectMethod · 0.80
allMethod · 0.80
base_eqMethod · 0.80
compatibleMethod · 0.80
iterMethod · 0.45
as_refMethod · 0.45
removeMethod · 0.45

Tested by

no test coverage detected