Пример #1
0
    def visit_TypeCast(self, node):
        if node.type.subtypes:
            typ = qlast.TypeName(
                maintype=qlast.ObjectRef(name=node.type.maintype),
                subtypes=[
                    qlast.ObjectRef(module=stn.module, name=stn.name)
                    for stn in node.type.subtypes
                ])
        else:
            mtn = node.type.maintype
            mt = qlast.ObjectRef(module=mtn.module, name=mtn.name)
            typ = qlast.TypeName(maintype=mt)

        result = qlast.TypeCast(expr=self.visit(node.expr), type=typ)

        return result
Пример #2
0
def compile_FunctionCall(
        expr: qlast.Base, *, ctx: context.ContextLevel) -> irast.Base:
    with ctx.new() as fctx:
        if isinstance(expr.func, str):
            funcname = expr.func
        else:
            funcname = sn.Name(expr.func[1], expr.func[0])

        funcs = fctx.schema.get_functions(
            funcname, module_aliases=fctx.modaliases)

        if funcs is None:
            raise errors.EdgeQLError(
                f'could not resolve function name {funcname}',
                context=expr.context)

        fctx.in_func_call = True
        args, kwargs, arg_types = process_func_args(expr, funcname, ctx=fctx)

        fatal_array_check = len(funcs) == 1
        for funcobj in funcs:
            if check_function(expr, funcname, funcobj, arg_types,
                              fatal_array_check=fatal_array_check):
                break
        else:
            raise errors.EdgeQLError(
                f'could not find a function variant {funcname}',
                context=expr.context)

        fixup_param_scope(funcobj, args, kwargs, ctx=fctx)

        node = irast.FunctionCall(func=funcobj, args=args, kwargs=kwargs)

        if funcobj.initial_value is not None:
            rtype = irutils.infer_type(node, fctx.schema)
            iv_ql = qlast.TypeCast(
                expr=qlparser.parse_fragment(funcobj.initial_value),
                type=typegen.type_to_ql_typeref(rtype)
            )
            node.initial_value = dispatch.compile(iv_ql, ctx=fctx)

    ir_set = setgen.ensure_set(node, ctx=ctx)
    return ir_set
Пример #3
0
    def visit_ObjectField(self, node):
        fname = node.name

        # handle boolean ops
        if fname == 'and':
            return self._visit_list_of_inputs(node.value.value, ast.ops.AND)
        elif fname == 'or':
            return self._visit_list_of_inputs(node.value.value, ast.ops.OR)
        elif fname == 'not':
            return qlast.UnaryOp(op=ast.ops.NOT,
                                 operand=self.visit(node.value))

        # handle various scalar ops
        op = gt.GQL_TO_OPS_MAP.get(fname)

        if op:
            value = self.visit(node.value)
            return qlast.BinOp(left=self._context.filter, op=op, right=value)

        # we're at the beginning of a scalar op
        _, target = self._get_parent_and_current_type()

        name = self.get_path_prefix()
        name.append(qlast.Ptr(ptr=qlast.ObjectRef(name=fname)))
        name = qlast.Path(steps=name)

        # potentially need to cast the 'name' side into a <str>, so as
        # to be compatible with the 'value'
        typename = target.get_field_type(fname).short_name
        if (typename != 'str' and gt.EDB_TO_GQL_SCALARS_MAP[typename]
                in {GraphQLString, GraphQLID}):
            name = qlast.TypeCast(
                expr=name,
                type=qlast.TypeName(maintype=qlast.ObjectRef(name='str')),
            )

        self._context.filter = name

        return self.visit(node.value)
Пример #4
0
    def visit_Argument(self, node, *, get_path_prefix):
        op = ast.ops.EQ
        name_parts = node.name

        _, target = self._get_parent_and_current_type()

        name = get_path_prefix()
        name.append(qlast.Ptr(ptr=qlast.ObjectRef(name=name_parts)))
        name = qlast.Path(steps=name)

        value = self.visit(node.value)

        # potentially need to cast the 'name' side into a <str>, so as
        # to be compatible with the 'value'
        typename = target.get_field_type(name_parts).short_name
        if (typename != 'str' and gt.EDB_TO_GQL_SCALARS_MAP[typename]
                in {GraphQLString, GraphQLID}):
            name = qlast.TypeCast(
                expr=name,
                type=qlast.TypeName(maintype=qlast.ObjectRef(name='str')),
            )

        return qlast.BinOp(left=name, op=op, right=value)
Пример #5
0
def compile_FunctionCall(expr: qlast.Base, *,
                         ctx: context.ContextLevel) -> irast.Base:

    env = ctx.env

    if isinstance(expr.func, str):
        if ctx.func is not None:
            ctx_func_params = ctx.func.get_params(env.schema)
            if ctx_func_params.get_by_name(env.schema, expr.func):
                raise errors.QueryError(
                    f'parameter `{expr.func}` is not callable',
                    context=expr.context)

        funcname = expr.func
    else:
        funcname = sn.Name(expr.func[1], expr.func[0])

    funcs = env.schema.get_functions(funcname, module_aliases=ctx.modaliases)

    if funcs is None:
        raise errors.QueryError(f'could not resolve function name {funcname}',
                                context=expr.context)

    args, kwargs = compile_call_args(expr, funcname, ctx=ctx)
    matched = polyres.find_callable(funcs, args=args, kwargs=kwargs, ctx=ctx)
    if not matched:
        raise errors.QueryError(
            f'could not find a function variant {funcname}',
            context=expr.context)
    elif len(matched) > 1:
        raise errors.QueryError(f'function {funcname} is not unique',
                                context=expr.context)
    else:
        matched_call = matched[0]

    args, params_typemods = finalize_args(matched_call, ctx=ctx)

    matched_func_params = matched_call.func.get_params(env.schema)
    variadic_param = matched_func_params.find_variadic(env.schema)
    variadic_param_type = None
    if variadic_param is not None:
        variadic_param_type = variadic_param.get_type(env.schema)

    matched_func_ret_type = matched_call.func.get_return_type(env.schema)
    is_polymorphic = (any(
        p.get_type(env.schema).is_polymorphic(env.schema)
        for p in matched_func_params.objects(env.schema))
                      and matched_func_ret_type.is_polymorphic(env.schema))

    matched_func_initial_value = matched_call.func.get_initial_value(
        env.schema)

    func = matched_call.func

    node = irast.FunctionCall(
        args=args,
        func_shortname=func.get_shortname(env.schema),
        func_polymorphic=is_polymorphic,
        func_sql_function=func.get_from_function(env.schema),
        force_return_cast=func.get_force_return_cast(env.schema),
        params_typemods=params_typemods,
        context=expr.context,
        stype=matched_call.return_type,
        typemod=matched_call.func.get_return_typemod(env.schema),
        has_empty_variadic=matched_call.has_empty_variadic,
        variadic_param_type=variadic_param_type,
    )

    if matched_func_initial_value is not None:
        rtype = inference.infer_type(node, env=ctx.env)
        iv_ql = qlast.TypeCast(
            expr=qlparser.parse_fragment(matched_func_initial_value),
            type=typegen.type_to_ql_typeref(rtype, ctx=ctx))
        node.func_initial_value = dispatch.compile(iv_ql, ctx=ctx)

    return setgen.ensure_set(node, typehint=matched_call.return_type, ctx=ctx)
Пример #6
0
 def reduce_LANGBRACKET_FullTypeExpr_RANGBRACKET_Expr(
         self, *kids):
     self.val = qlast.TypeCast(expr=kids[3].val, type=kids[1].val)