def sdl_to_ddl(schema, documents): ddlgraph = {} mods = [] ctx = LayoutTraceContext( schema, local_modules=frozenset(mod for mod, schema_decl in documents.items()), ) for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: if isinstance(decl_ast, qlast.CreateObject): _, fq_name = ctx.get_fq_name(decl_ast) if isinstance(decl_ast, (qlast.CreateObjectType, qlast.CreateAlias)): ctx.objects[fq_name] = qltracer.ObjectType(fq_name) elif isinstance(decl_ast, qlast.CreateScalarType): ctx.objects[fq_name] = qltracer.Type(fq_name) elif isinstance(decl_ast, (qlast.CreateLink, qlast.CreateProperty)): ctx.objects[fq_name] = qltracer.Pointer(fq_name, source=None, target=None) elif isinstance(decl_ast, qlast.CreateFunction): ctx.objects[fq_name] = qltracer.Function(fq_name) elif isinstance(decl_ast, qlast.CreateConstraint): ctx.objects[fq_name] = qltracer.Constraint(fq_name) elif isinstance(decl_ast, qlast.CreateAnnotation): ctx.objects[fq_name] = qltracer.Annotation(fq_name) else: raise AssertionError( f'unexpected SDL declaration: {decl_ast}') for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: trace_layout(decl_ast, ctx=ctx) # compute the ancestors graph for fq_name in ctx.parents.keys(): ctx.ancestors[fq_name] = get_ancestors(fq_name, ctx.ancestors, ctx.parents) topological.normalize(ctx.inh_graph, _merge_items) ctx = DepTraceContext(schema, ddlgraph, ctx.objects, ctx.parents, ctx.ancestors, ctx.defdeps, ctx.constraints) for module_name, declarations in documents.items(): ctx.set_module(module_name) # module needs to be created regardless of whether its # contents are empty or not mods.append(qlast.CreateModule(name=qlast.ObjectRef(name=module_name))) for decl_ast in declarations: trace_dependencies(decl_ast, ctx=ctx) return mods + list(topological.sort(ddlgraph, allow_unresolved=False))
def sdl_to_ddl( schema: s_schema.Schema, documents: Mapping[str, List[qlast.DDL]], ) -> Tuple[qlast.DDLCommand, ...]: ddlgraph: DDLGraph = {} mods: List[qlast.DDLCommand] = [] ctx = LayoutTraceContext( schema, local_modules=frozenset(mod for mod in documents), ) for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: if isinstance(decl_ast, qlast.CreateObject): _, fq_name = ctx.get_fq_name(decl_ast) if isinstance(decl_ast, (qlast.CreateObjectType, qlast.CreateAlias)): ctx.objects[fq_name] = qltracer.ObjectType(fq_name) elif isinstance(decl_ast, qlast.CreateScalarType): ctx.objects[fq_name] = qltracer.Type(fq_name) elif isinstance(decl_ast, (qlast.CreateLink, qlast.CreateProperty)): ctx.objects[fq_name] = qltracer.Pointer( fq_name, source=None, target=None) elif isinstance(decl_ast, qlast.CreateFunction): ctx.objects[fq_name] = qltracer.Function(fq_name) elif isinstance(decl_ast, qlast.CreateConstraint): ctx.objects[fq_name] = qltracer.Constraint(fq_name) elif isinstance(decl_ast, qlast.CreateAnnotation): ctx.objects[fq_name] = qltracer.Annotation(fq_name) else: raise AssertionError( f'unexpected SDL declaration: {decl_ast}') for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: trace_layout(decl_ast, ctx=ctx) # compute the ancestors graph for obj_name in ctx.parents.keys(): ctx.ancestors[obj_name] = get_ancestors( obj_name, ctx.ancestors, ctx.parents) topological.normalize( ctx.inh_graph, merger=_graph_merge_cb, # type: ignore schema=schema, ) tracectx = DepTraceContext( schema, ddlgraph, ctx.objects, ctx.parents, ctx.ancestors, ctx.defdeps, ctx.constraints ) for module_name, declarations in documents.items(): tracectx.set_module(module_name) # module needs to be created regardless of whether its # contents are empty or not mods.append(qlast.CreateModule(name=qlast.ObjectRef(name=module_name))) for decl_ast in declarations: trace_dependencies(decl_ast, ctx=tracectx) ordered = topological.sort(ddlgraph, allow_unresolved=False) return tuple(mods) + tuple(ordered)
def sdl_to_ddl( schema: s_schema.Schema, documents: Mapping[str, List[qlast.DDL]], ) -> Tuple[qlast.DDLCommand, ...]: ddlgraph: DDLGraph = {} mods: List[qlast.DDLCommand] = [] ctx = LayoutTraceContext( schema, local_modules=frozenset(mod for mod in documents), ) for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: if isinstance(decl_ast, qlast.CreateObject): _, fq_name = ctx.get_fq_name(decl_ast) if isinstance(decl_ast, qlast.CreateObjectType): ctx.objects[fq_name] = qltracer.ObjectType(fq_name) elif isinstance(decl_ast, qlast.CreateAlias): ctx.objects[fq_name] = qltracer.Alias(fq_name) elif isinstance(decl_ast, qlast.CreateScalarType): ctx.objects[fq_name] = qltracer.ScalarType(fq_name) elif isinstance(decl_ast, qlast.CreateLink): ctx.objects[fq_name] = qltracer.Link(fq_name, source=None, target=None) elif isinstance(decl_ast, qlast.CreateProperty): ctx.objects[fq_name] = qltracer.Property(fq_name, source=None, target=None) elif isinstance(decl_ast, qlast.CreateFunction): ctx.objects[fq_name] = qltracer.Function(fq_name) elif isinstance(decl_ast, qlast.CreateConstraint): ctx.objects[fq_name] = qltracer.Constraint(fq_name) elif isinstance(decl_ast, qlast.CreateAnnotation): ctx.objects[fq_name] = qltracer.Annotation(fq_name) else: raise AssertionError( f'unexpected SDL declaration: {decl_ast}') for module_name, declarations in documents.items(): ctx.set_module(module_name) for decl_ast in declarations: trace_layout(decl_ast, ctx=ctx) # compute the ancestors graph for obj_name in ctx.parents.keys(): ctx.ancestors[obj_name] = get_ancestors(obj_name, ctx.ancestors, ctx.parents) topological.normalize( ctx.inh_graph, merger=_graph_merge_cb, # type: ignore schema=schema, ) tracectx = DepTraceContext(schema, ddlgraph, ctx.objects, ctx.parents, ctx.ancestors, ctx.defdeps, ctx.constraints) for module_name, declarations in documents.items(): tracectx.set_module(module_name) # module needs to be created regardless of whether its # contents are empty or not mods.append(qlast.CreateModule(name=qlast.ObjectRef(name=module_name))) for decl_ast in declarations: trace_dependencies(decl_ast, ctx=tracectx) try: ordered = topological.sort(ddlgraph, allow_unresolved=False) except topological.CycleError as e: assert isinstance(e.item, s_name.QualName) node = tracectx.ddlgraph[e.item].item item_vn = get_verbosename_from_fqname(e.item, tracectx) if e.path is not None and len(e.path): # Recursion involving more than one schema object. rec_vn = get_verbosename_from_fqname(e.path[-1], tracectx) msg = (f'definition dependency cycle between {rec_vn} ' f'and {item_vn}') else: # A single schema object with a recursive definition. msg = f'{item_vn} is defined recursively' raise errors.InvalidDefinitionError(msg, context=node.context) from e return tuple(mods) + tuple(ordered)