def run_test(self, *, source, spec, expected): qltree = qlparser.parse(source) ir = compiler.compile_ast_to_ir(qltree, self.schema) # The expected cardinality is either given for the whole query # (by default) or for a specific element of the top-level # shape. In case of the specific element the name of the shape # element must be given followed by ":" and then the # cardinality. exp = textwrap.dedent(expected).strip(' \n').split(':') if len(exp) == 1: field = None expected_cardinality = qltypes.Cardinality(exp[0]) elif len(exp) == 2: field = exp[0].strip() expected_cardinality = qltypes.Cardinality(exp[1].strip()) else: raise ValueError( f'unrecognized expected specification: {expected!r}') if field is not None: shape = ir.expr.expr.result.shape for el, _ in shape: if str(el.path_id.rptr_name()).endswith(field): card = el.rptr.ptrref.out_cardinality self.assertEqual(card, expected_cardinality, 'unexpected cardinality:\n' + source) break else: raise AssertionError(f'shape field not found: {field!r}') else: self.assertEqual(ir.cardinality, expected_cardinality, 'unexpected cardinality:\n' + source)
def run_test(self, *, source, spec, expected): qltree = qlparser.parse(source) ir = compiler.compile_ast_to_ir(qltree, self.schema) expected_cardinality = qltypes.Cardinality( textwrap.dedent(expected).strip(' \n')) self.assertEqual(ir.cardinality, expected_cardinality, 'unexpected cardinality:\n' + source)
async def read_link_properties(self, schema, only_modules, exclude_modules): link_props = await datasources.schema.links.fetch_properties( self.connection, modules=only_modules, exclude_modules=exclude_modules) link_props = {sn.Name(r['name']): r for r in link_props} basemap = {} exprmap = {} for name, r in link_props.items(): bases = () if r['bases']: bases = tuple(sn.Name(b) for b in r['bases']) elif name != 'std::property': bases = (sn.Name('std::property'), ) source = schema.get(r['source']) if r['source'] else None required = r['required'] target = self.unpack_typeref(r['target'], schema) if target is not None and target.is_collection(): schema, _ = target.as_schema_coll(schema) if r['cardinality']: cardinality = qltypes.Cardinality(r['cardinality']) else: cardinality = None schema, prop = s_props.Property.create_in_schema( schema, id=r['id'], inherited_fields=self._unpack_inherited_fields( r['inherited_fields']), name=name, source=source, target=target, required=required, readonly=r['readonly'], expr=(self.unpack_expr(r['expr'], schema) if r['expr'] else None), cardinality=cardinality, is_derived=r['is_derived'], is_local=r['is_local'], is_abstract=r['is_abstract'], is_final=r['is_final']) basemap[prop] = (bases, r['ancestors']) if r['default']: exprmap[prop] = r['default'] if bases and bases[0] in {'std::target', 'std::source'}: if bases[0] == 'std::target' and source is not None: target = source.get_target(schema) elif bases[0] == 'std::source' and source is not None: target = source.get_source(schema) schema = prop.set_field_value(schema, 'target', target) if source: schema = source.add_pointer(schema, prop) for scls, (basenames, ancestors) in basemap.items(): schema = self._set_reflist(schema, scls, 'bases', basenames) schema = self._set_reflist(schema, scls, 'ancestors', ancestors) return schema, exprmap
async def read_links(self, schema, only_modules, exclude_modules): link_tables = await introspection.tables.fetch_tables( self.connection, schema_pattern='edgedb%', table_pattern='%_link') link_tables = {(t['schema'], t['name']): t for t in link_tables} links_list = await datasources.schema.links.fetch( self.connection, modules=only_modules, exclude_modules=exclude_modules) links_list = {sn.Name(r['name']): r for r in links_list} basemap = {} exprmap = {} for name, r in links_list.items(): bases = tuple() if r['bases']: bases = tuple(sn.Name(b) for b in r['bases']) elif name != 'std::link': bases = (sn.Name('std::link'), ) source = schema.get(r['source']) if r['source'] else None target = self.unpack_typeref(r['target'], schema) required = r['required'] if r['cardinality']: cardinality = qltypes.Cardinality(r['cardinality']) else: cardinality = None schema, link = s_links.Link.create_in_schema( schema, id=r['id'], inherited_fields=self._unpack_inherited_fields( r['inherited_fields']), name=name, source=source, target=target, cardinality=cardinality, required=required, is_derived=r['is_derived'], is_abstract=r['is_abstract'], is_final=r['is_final'], is_local=r['is_local'], readonly=r['readonly'], expr=(self.unpack_expr(r['expr'], schema) if r['expr'] else None), ) if r['default']: exprmap[link] = r['default'] basemap[link] = (bases, r['ancestors']) schema = link.set_field_value(schema, 'target', target) if source: schema = source.add_pointer(schema, link) for scls, (basenames, ancestors) in basemap.items(): schema = self._set_reflist(schema, scls, 'bases', basenames) schema = self._set_reflist(schema, scls, 'ancestors', ancestors) return schema, exprmap
async def read_link_properties(self, schema, only_modules, exclude_modules): link_props = await datasources.schema.links.fetch_properties( self.connection, modules=only_modules, exclude_modules=exclude_modules) link_props = {sn.Name(r['name']): r for r in link_props} basemap = {} for name, r in link_props.items(): bases = () if r['bases']: bases = tuple(sn.Name(b) for b in r['bases']) elif name != 'std::property': bases = (sn.Name('std::property'), ) source = schema.get(r['source']) if r['source'] else None if r['derived_from']: derived_from = schema.get(r['derived_from']) else: derived_from = None if r['default']: default = self.unpack_expr(r['default'], schema) else: default = None required = r['required'] target = self.unpack_typeref(r['target'], schema) basemap[name] = bases if target.is_collection(): schema, _ = target.as_schema_coll(schema) if r['cardinality']: cardinality = qltypes.Cardinality(r['cardinality']) else: cardinality = None schema, prop = s_props.Property.create_in_schema( schema, id=r['id'], name=name, source=source, target=target, required=required, readonly=r['readonly'], computable=r['computable'], default=default, cardinality=cardinality, derived_from=derived_from, is_derived=r['is_derived'], is_abstract=r['is_abstract'], is_final=r['is_final']) if bases and bases[0] in {'std::target', 'std::source'}: if bases[0] == 'std::target' and source is not None: target = source.get_target(schema) elif bases[0] == 'std::source' and source is not None: target = source.get_source(schema) schema = prop.set_field_value(schema, 'target', target) if source: schema = prop.acquire_ancestor_inheritance(schema) schema = source.add_pointer(schema, prop) for prop in schema.get_objects(type=s_props.Property): try: bases = basemap[prop.get_name(schema)] except KeyError: pass else: schema = prop.set_field_value( schema, 'bases', [schema.get(b, type=s_props.Property) for b in bases]) return schema
async def read_links(self, schema, only_modules, exclude_modules): link_tables = await introspection.tables.fetch_tables( self.connection, schema_pattern='edgedb%', table_pattern='%_link') link_tables = {(t['schema'], t['name']): t for t in link_tables} links_list = await datasources.schema.links.fetch( self.connection, modules=only_modules, exclude_modules=exclude_modules) links_list = {sn.Name(r['name']): r for r in links_list} basemap = {} dermap = {} for name, r in links_list.items(): bases = tuple() if r['bases']: bases = tuple(sn.Name(b) for b in r['bases']) elif name != 'std::link': bases = (sn.Name('std::link'), ) if r['derived_from']: dermap[name] = r['derived_from'] source = schema.get(r['source']) if r['source'] else None if r['spectargets']: spectargets = [schema.get(t) for t in r['spectargets']] target = None else: spectargets = None target = self.unpack_typeref(r['target'], schema) if r['default']: default = self.unpack_expr(r['default'], schema) else: default = None required = r['required'] if r['cardinality']: cardinality = qltypes.Cardinality(r['cardinality']) else: cardinality = None basemap[name] = bases schema, link = s_links.Link.create_in_schema( schema, id=r['id'], name=name, source=source, target=target, spectargets=spectargets, cardinality=cardinality, required=required, is_derived=r['is_derived'], is_abstract=r['is_abstract'], is_final=r['is_final'], readonly=r['readonly'], computable=r['computable'], default=default) if spectargets: # Multiple specified targets, # target is a virtual derived object schema, target = link.create_common_target(schema, spectargets) schema = link.set_field_value(schema, 'target', target) if source: schema = source.add_pointer(schema, link) for link in schema.get_objects(type=s_links.Link): try: bases = basemap[link.get_name(schema)] except KeyError: pass else: schema = link.set_field_value(schema, 'bases', [schema.get(b) for b in bases]) try: derived_from = dermap[link.get_name(schema)] except KeyError: pass else: schema = link.set_field_value(schema, 'derived_from', schema.get(derived_from)) for link in schema.get_objects(type=s_links.Link): schema = link.acquire_ancestor_inheritance(schema) return schema