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

Function handle_mutation_using_clause

src/sql/src/plan/query.rs:852–941  ·  view source on GitHub ↗

Adjust `get` to perform an existential subquery on `using` accounting for `selection`. If `USING`, we essentially want to rewrite the query as a correlated existential subquery, i.e. ``` ...WHERE EXISTS (SELECT 1 FROM WHERE ) ``` However, we can't do that directly because of esoteric rules w/r/t `lateral` subqueries. https://github.com/postgres/postgres/commit/158b7fa6a34006bdc

(
    qcx: &QueryContext,
    selection: Option<Expr<Aug>>,
    using: Vec<TableWithJoins<Aug>>,
    get: HirRelationExpr,
    outer_scope: Scope,
)

Source from the content-addressed store, hash-verified

850// subqueries.
851// https://github.com/postgres/postgres/commit/158b7fa6a34006bdc70b515e14e120d3e896589b
852fn handle_mutation_using_clause(
853 qcx: &QueryContext,
854 selection: Option<Expr<Aug>>,
855 using: Vec<TableWithJoins<Aug>>,
856 get: HirRelationExpr,
857 outer_scope: Scope,
858) -> Result<HirRelationExpr, PlanError> {
859 // Plan `USING` as a cross-joined `FROM` without knowledge of the
860 // statement's `FROM` target. This prevents `lateral` subqueries from
861 // "seeing" the `FROM` target.
862 let (mut using_rel_expr, using_scope) =
863 using.into_iter().try_fold(plan_join_identity(), |l, twj| {
864 let (left, left_scope) = l;
865 plan_join(
866 qcx,
867 left,
868 left_scope,
869 &Join {
870 relation: TableFactor::NestedJoin {
871 join: Box::new(twj),
872 alias: None,
873 },
874 join_operator: JoinOperator::CrossJoin,
875 },
876 )
877 })?;
878
879 if let Some(expr) = selection {
880 // Join `FROM` with `USING` tables, like `USING..., FROM`. This gives us
881 // PG-like semantics e.g. expressing ambiguous column references. We put
882 // `USING...` first for no real reason, but making a different decision
883 // would require adjusting the column references on this relation
884 // differently.
885 let on = HirScalarExpr::literal_true();
886 let joined = using_rel_expr
887 .clone()
888 .join(get.clone(), on, JoinKind::Inner);
889 let joined_scope = using_scope.product(outer_scope)?;
890 let joined_relation_type = qcx.relation_type(&joined);
891
892 let ecx = &ExprContext {
893 qcx,
894 name: "WHERE clause",
895 scope: &joined_scope,
896 relation_type: &joined_relation_type,
897 allow_aggregates: false,
898 allow_subqueries: true,
899 allow_parameters: true,
900 allow_windows: false,
901 };
902
903 // Plan the filter expression on `FROM, USING...`.
904 let mut expr = plan_expr(ecx, &expr)?.type_as(ecx, &SqlScalarType::Bool)?;
905
906 // Rewrite all column referring to the `FROM` section of `joined` (i.e.
907 // those to the right of `using_rel_expr`) to instead be correlated to
908 // the outer relation, i.e. `get`.
909 let using_rel_arity = qcx.relation_type(&using_rel_expr).arity();

Callers 1

Calls 12

plan_join_identityFunction · 0.85
plan_joinFunction · 0.85
plan_exprFunction · 0.85
relation_typeMethod · 0.80
type_asMethod · 0.80
visit_mut_postMethod · 0.80
into_iterMethod · 0.45
joinMethod · 0.45
cloneMethod · 0.45
productMethod · 0.45
arityMethod · 0.45
filterMethod · 0.45

Tested by

no test coverage detected