def compile_DeleteQuery( expr: qlast.Base, *, ctx: context.ContextLevel) -> irast.Base: with ctx.subquery() as ictx: ictx.implicit_id_in_shapes = False ictx.implicit_tid_in_shapes = False stmt = irast.DeleteStmt() # Expand the DELETE from sugar into full DELETE (SELECT ...) # form, if there's any additional clauses. if any([expr.where, expr.orderby, expr.offset, expr.limit]): expr = qlast.DeleteQuery( aliases=expr.aliases, subject=qlast.SelectQuery( result=expr.subject, result_alias=expr.subject_alias, where=expr.where, orderby=expr.orderby, offset=expr.offset, limit=expr.limit, context=expr.context, ), context=expr.context, ) init_stmt(stmt, expr, ctx=ictx, parent_ctx=ctx) # DELETE Expr is a delete(SET OF X), so we need a scope fence. with ictx.newscope(fenced=True) as scopectx: subject = setgen.scoped_set( dispatch.compile(expr.subject, ctx=scopectx), ctx=scopectx) subj_type = inference.infer_type(subject, ictx.env) if not isinstance(subj_type, s_objtypes.ObjectType): raise errors.QueryError( f'cannot delete non-ObjectType objects', context=expr.subject.context ) stmt.subject = compile_query_subject(subject, shape=None, ctx=ictx) stmt_subject_stype = setgen.get_set_type(subject, ctx=ictx) result = setgen.class_set( stmt_subject_stype.material_type(ctx.env.schema), path_id=stmt.subject.path_id, ctx=ctx) stmt.result = compile_query_subject( result, view_scls=ctx.view_scls, view_name=ctx.toplevel_result_view_name, compile_views=ictx.stmt is ictx.toplevel_stmt, ctx=ictx) result = fini_stmt(stmt, expr, ctx=ictx, parent_ctx=ctx) return result
def compile_DeleteQuery( expr: qlast.DeleteQuery, *, ctx: context.ContextLevel) -> irast.Set: if ctx.in_conditional is not None: raise errors.QueryError( 'DELETE statements cannot be used inside conditional expressions', context=expr.context, ) with ctx.subquery() as ictx: stmt = irast.DeleteStmt() # Expand the DELETE from sugar into full DELETE (SELECT ...) # form, if there's any additional clauses. if any([expr.where, expr.orderby, expr.offset, expr.limit]): if expr.offset or expr.limit: subjql = qlast.SelectQuery( result=qlast.SelectQuery( result=expr.subject, result_alias=expr.subject_alias, where=expr.where, orderby=expr.orderby, context=expr.context, implicit=True, ), limit=expr.limit, offset=expr.offset, context=expr.context, ) else: subjql = qlast.SelectQuery( result=expr.subject, result_alias=expr.subject_alias, where=expr.where, orderby=expr.orderby, offset=expr.offset, limit=expr.limit, context=expr.context, ) expr = qlast.DeleteQuery( aliases=expr.aliases, context=expr.context, subject=subjql, ) init_stmt(stmt, expr, ctx=ictx, parent_ctx=ctx) # DELETE Expr is a delete(SET OF X), so we need a scope fence. with ictx.newscope(fenced=True) as scopectx: scopectx.implicit_limit = 0 subject = setgen.scoped_set( dispatch.compile(expr.subject, ctx=scopectx), ctx=scopectx) subj_type = inference.infer_type(subject, ictx.env) if not isinstance(subj_type, s_objtypes.ObjectType): raise errors.QueryError( f'cannot delete non-ObjectType objects', context=expr.subject.context ) with ictx.new() as bodyctx: bodyctx.implicit_id_in_shapes = False bodyctx.implicit_tid_in_shapes = False stmt.subject = compile_query_subject( subject, shape=None, is_delete=True, ctx=bodyctx, ) stmt_subject_stype = setgen.get_set_type(subject, ctx=ictx) result = setgen.class_set( schemactx.get_material_type(stmt_subject_stype, ctx=ctx), path_id=stmt.subject.path_id, ctx=ctx, ) with ictx.new() as resultctx: if ictx.stmt is ctx.toplevel_stmt: resultctx.expr_exposed = True stmt.result = compile_query_subject( result, view_scls=ctx.view_scls, view_name=ctx.toplevel_result_view_name, compile_views=ictx.stmt is ictx.toplevel_stmt, ctx=resultctx, ) result = fini_stmt(stmt, expr, ctx=ictx, parent_ctx=ctx) return result