示例#1
0
def assign_set_scope(ir_set: irast.Set, scope: Optional[irast.ScopeTreeNode],
                     *, ctx: context.ContextLevel) -> irast.Set:
    if scope is None:
        ir_set.path_scope_id = None
    else:
        if scope.unique_id is None:
            scope.unique_id = ctx.scope_id_ctr.nextval()
        ir_set.path_scope_id = scope.unique_id
        if scope.find_child(ir_set.path_id):
            raise RuntimeError('scoped set must not contain itself')

    return ir_set
示例#2
0
文件: config.py 项目: yew1eb/edgedb
def _rewrite_config_insert(ir_set: irast.Set, *,
                           ctx: context.CompilerContextLevel) -> irast.Set:

    relctx.add_type_rel_overlay(
        ir_set.typeref,
        'replace',
        pgast.NullRelation(path_id=ir_set.path_id),
        path_id=ir_set.path_id,
        ctx=ctx,
    )

    # Config objects have derived computed ids,
    # so the autogenerated id must not be returned.
    ir_set.shape = list(
        filter(
            lambda el: el[0].rptr.ptrref.shortname.name != 'id',
            ir_set.shape,
        ))

    for el, _ in ir_set.shape:
        if isinstance(el.expr, irast.InsertStmt):
            el.shape = list(
                filter(
                    lambda e: e[0].rptr.ptrref.shortname.name != 'id',
                    el.shape,
                ))

            result = _rewrite_config_insert(el.expr.subject, ctx=ctx)
            el.expr = irast.SelectStmt(
                result=result,
                parent_stmt=el.expr.parent_stmt,
            )

    return ir_set
示例#3
0
def _rewrite_config_insert(ir_set: irast.Set, *,
                           ctx: context.CompilerContextLevel) -> irast.Set:

    overwrite_query = pgast.SelectStmt()
    id_expr = pgast.FuncCall(
        name=(
            'edgedbext',
            'uuid_generate_v1mc',
        ),
        args=[],
    )
    pathctx.put_path_identity_var(overwrite_query,
                                  ir_set.path_id,
                                  id_expr,
                                  force=True,
                                  env=ctx.env)
    pathctx.put_path_value_var(overwrite_query,
                               ir_set.path_id,
                               id_expr,
                               force=True,
                               env=ctx.env)
    pathctx.put_path_source_rvar(overwrite_query,
                                 ir_set.path_id,
                                 relctx.rvar_for_rel(pgast.NullRelation(),
                                                     ctx=ctx),
                                 env=ctx.env)

    relctx.add_type_rel_overlay(
        ir_set.typeref,
        'replace',
        overwrite_query,
        path_id=ir_set.path_id,
        ctx=ctx,
    )

    # Config objects have derived computed ids,
    # so the autogenerated id must not be returned.
    ir_set.shape = tuple(
        filter(
            lambda el: ((rptr := el[0].rptr) is not None and rptr.ptrref.
                        shortname.name != 'id'),
            ir_set.shape,
        ))

    for el, _ in ir_set.shape:
        if isinstance(el.expr, irast.InsertStmt):
            el.shape = tuple(
                filter(
                    lambda e: ((rptr := e[0].rptr) is not None and rptr.ptrref.
                               shortname.name != 'id'),
                    el.shape,
                ))

            result = _rewrite_config_insert(el.expr.subject, ctx=ctx)
            el.expr = irast.SelectStmt(
                result=result,
                parent_stmt=el.expr.parent_stmt,
            )

    return ir_set
示例#4
0
def _compile_view_shapes_in_set(
        ir_set: irast.Set, *,
        rptr: Optional[irast.Pointer]=None,
        parent_view_type: Optional[s_types.ExprType]=None,
        ctx: context.ContextLevel) -> None:

    shape_ptrs = _get_shape_configuration(
        ir_set, rptr=rptr, parent_view_type=parent_view_type, ctx=ctx)

    # We want to push down the shape to better correspond with where it
    # appears in the query (rather than lifting it up to the first
    # place the view_type appears---this is a little hacky, because
    # letting it be lifted up is the natural thing with our view type-driven
    # shape compilation).
    #
    # This is to avoid losing subquery distinctions (in cases
    # like test_edgeql_scope_tuple_15), and generally seems more natural.
    if (isinstance(ir_set.expr, irast.SelectStmt)
            and (setgen.get_set_type(ir_set, ctx=ctx) ==
                 setgen.get_set_type(ir_set.expr.result, ctx=ctx))):
        child = ir_set.expr.result
        set_scope = pathctx.get_set_scope(ir_set, ctx=ctx)

        if shape_ptrs:
            pathctx.register_set_in_scope(ir_set, ctx=ctx)
        with ctx.new() as scopectx:
            if set_scope is not None:
                scopectx.path_scope = set_scope
            compile_view_shapes(
                child,
                rptr=rptr or ir_set.rptr,
                parent_view_type=parent_view_type,
                ctx=scopectx)

        ir_set.shape_source = child if child.shape else child.shape_source
        return

    if shape_ptrs:
        pathctx.register_set_in_scope(ir_set, ctx=ctx)
        stype = setgen.get_set_type(ir_set, ctx=ctx)

        # If the shape has already been populated (because the set is
        # referenced multiple times), then we've got nothing to do.
        if ir_set.shape:
            return

        shape = []
        for path_tip, ptr, shape_op in shape_ptrs:
            srcctx = None
            if ptr in ctx.env.pointer_specified_info:
                _, _, srcctx = ctx.env.pointer_specified_info[ptr]

            element = setgen.extend_path(
                path_tip,
                ptr,
                same_computable_scope=True,
                srcctx=srcctx,
                ctx=ctx,
            )

            element_scope = pathctx.get_set_scope(element, ctx=ctx)

            if element_scope is None:
                element_scope = ctx.path_scope.attach_fence()
                pathctx.assign_set_scope(element, element_scope, ctx=ctx)

            if element_scope.namespaces:
                element.path_id = element.path_id.merge_namespace(
                    element_scope.namespaces)

            with ctx.new() as scopectx:
                scopectx.path_scope = element_scope
                compile_view_shapes(
                    element,
                    parent_view_type=stype.get_expr_type(ctx.env.schema),
                    ctx=scopectx)

            shape.append((element, shape_op))

        ir_set.shape = tuple(shape)

    elif ir_set.expr is not None:
        set_scope = pathctx.get_set_scope(ir_set, ctx=ctx)
        if set_scope is not None:
            with ctx.new() as scopectx:
                scopectx.path_scope = set_scope
                compile_view_shapes(ir_set.expr, ctx=scopectx)
        else:
            compile_view_shapes(ir_set.expr, ctx=ctx)

    elif isinstance(ir_set.rptr, irast.TupleIndirectionPointer):
        compile_view_shapes(ir_set.rptr.source, ctx=ctx)