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)
Ejemplo n.º 2
0
 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)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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