Esempio n. 1
0
def compile_Set(
        expr: qlast.Base, *, ctx: context.ContextLevel) -> irast.Base:
    if expr.elements:
        if len(expr.elements) == 1:
            # From the scope perspective, single-element set
            # literals are equivalent to a binary UNION with
            # an empty set, not to the element.
            with ctx.newscope(fenced=True) as scopectx:
                ir_set = dispatch.compile(expr.elements[0], ctx=scopectx)
                return setgen.scoped_set(ir_set, ctx=scopectx)
        else:
            elements = flatten_set(expr)
            # a set literal is just sugar for a UNION
            op = qlast.UNION

            bigunion = qlast.BinOp(
                left=elements[0],
                right=elements[1],
                op=op
            )
            for el in elements[2:]:
                bigunion = qlast.BinOp(
                    left=bigunion,
                    right=el,
                    op=op
                )
            return dispatch.compile(bigunion, ctx=ctx)
    else:
        return irutils.new_empty_set(ctx.schema, alias=ctx.aliases.get('e'))
Esempio n. 2
0
    def _join_expressions(self, exprs, op='AND'):
        if not exprs:
            return None
        elif len(exprs) == 1:
            return exprs[0]

        result = qlast.BinOp(left=exprs[0], op=op, right=exprs[1])
        for expr in exprs[2:]:
            result = qlast.BinOp(left=result, op=op, right=expr)

        return result
Esempio n. 3
0
 def visit_TypeCheckOp(self, node):
     result = qlast.BinOp()
     result.left = self.visit(node.left)
     # Trim the trailing __type__ added by the compiler
     result.left.steps = result.left.steps[:-1]
     result.right = self.visit(node.right)
     result.op = node.op
     return result
Esempio n. 4
0
def extend_qlbinop(binop, *exprs, op=ast.ops.AND):
    exprs = list(exprs)
    binop = binop or exprs.pop(0)

    for expr in exprs:
        if expr is not binop:
            binop = qlast.BinOp(left=binop, right=expr, op=op)

    return binop
Esempio n. 5
0
    def reduce_Expr_OP_Expr(self, *kids):
        op = kids[1].val
        if op == '!=':
            op = ast.ops.NE
        elif op == '=':
            op = ast.ops.EQ
        elif op == '>=':
            op = ast.ops.GE
        elif op == '<=':
            op = ast.ops.LE
        elif op == '?=':
            op = qlast.EQUIVALENT
        elif op == '?!=':
            op = qlast.NEQUIVALENT

        self.val = qlast.BinOp(left=kids[0].val, op=op, right=kids[2].val)
Esempio n. 6
0
    def visit_OperatorCall(self, node):
        args = node.args

        if node.operator_kind is ft.OperatorKind.INFIX:
            result = qlast.BinOp(
                left=self.visit(args[0]),
                right=self.visit(args[1]),
                op=node.func_shortname.name,
            )
        elif node.operator_kind is ft.OperatorKind.PREFIX:
            result = qlast.UnaryOp(
                operand=self.visit(args[0]),
                op=node.func_shortname.name,
            )
        else:
            raise RuntimeError(
                f'unexpected operator kind: {node.operator_kind}')

        return result
Esempio n. 7
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)
Esempio n. 8
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)
Esempio n. 9
0
 def reduce_Expr_OR_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op=kids[1].val.upper(),
                            right=kids[2].val)
Esempio n. 10
0
 def reduce_Expr_EQUALS_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op=kids[1].val,
                            right=kids[2].val)
Esempio n. 11
0
 def reduce_Expr_RANGBRACKET_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op=kids[1].val,
                            right=kids[2].val)
Esempio n. 12
0
 def reduce_Expr_CIRCUMFLEX_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op=kids[1].val,
                            right=kids[2].val)
Esempio n. 13
0
 def reduce_Expr_DOUBLESLASH_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op=kids[1].val,
                            right=kids[2].val)
Esempio n. 14
0
 def visit_BinOp(self, node):
     result = qlast.BinOp()
     result.left = self.visit(node.left)
     result.right = self.visit(node.right)
     result.op = node.op
     return result
Esempio n. 15
0
 def reduce_Expr_IN_Expr(self, *kids):
     inexpr = kids[2].val
     self.val = qlast.BinOp(left=kids[0].val, op=ast.ops.IN, right=inexpr)
Esempio n. 16
0
 def reduce_Expr_LIKE_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op='LIKE',
                            right=kids[2].val)
Esempio n. 17
0
 def reduce_Expr_NOT_IN_Expr(self, *kids):
     inexpr = kids[3].val
     self.val = qlast.BinOp(left=kids[0].val, op='NOT IN',
                            right=inexpr)
Esempio n. 18
0
 def reduce_Expr_LANGBRACKET_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.LT,
                            right=kids[2].val)
Esempio n. 19
0
 def reduce_Expr_PERCENT_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.MOD,
                            right=kids[2].val)
Esempio n. 20
0
 def reduce_Expr_SLASH_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.DIV,
                            right=kids[2].val)
Esempio n. 21
0
 def reduce_Expr_MINUS_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.SUB,
                            right=kids[2].val)
Esempio n. 22
0
def compile_func_to_ir(func,
                       schema,
                       *,
                       anchors=None,
                       security_context=None,
                       modaliases=None,
                       implicit_id_in_shapes=False):
    """Compile an EdgeQL function into EdgeDB IR."""

    if debug.flags.edgeql_compile:
        debug.header('EdgeQL Function')
        debug.print(func.get_code(schema))

    trees = ql_parser.parse_block(func.get_code(schema) + ';')
    if len(trees) != 1:
        raise errors.InvalidFunctionDefinitionError(
            'functions can only contain one statement')

    tree = trees[0]
    if modaliases:
        ql_parser.append_module_aliases(tree, modaliases)

    if anchors is None:
        anchors = {}

    anchors['__defaults_mask__'] = irast.Parameter(
        name='__defaults_mask__', stype=schema.get('std::bytes'))

    func_params = func.get_params(schema)
    pg_params = s_func.PgParams.from_params(schema, func_params)
    for pi, p in enumerate(pg_params.params):
        p_shortname = p.get_shortname(schema)
        anchors[p_shortname] = irast.Parameter(name=p_shortname,
                                               stype=p.get_type(schema))

        if p.get_default(schema) is None:
            continue

        tree.aliases.append(
            qlast.AliasedExpr(
                alias=p_shortname,
                expr=qlast.
                IfElse(condition=qlast.BinOp(left=qlast.FunctionCall(
                    func=('std', 'bytes_get_bit'),
                    args=[
                        qlast.FuncArg(arg=qlast.Path(
                            steps=[qlast.ObjectRef(
                                name='__defaults_mask__')])),
                        qlast.FuncArg(arg=qlast.IntegerConstant(value=str(pi)))
                    ]),
                                             right=qlast.IntegerConstant(
                                                 value='0'),
                                             op='='),
                       if_expr=qlast.Path(
                           steps=[qlast.ObjectRef(name=p_shortname)]),
                       else_expr=qlast._Optional(
                           expr=p.get_ql_default(schema)))))

    ir = compile_ast_to_ir(tree,
                           schema,
                           anchors=anchors,
                           func=func,
                           security_context=security_context,
                           modaliases=modaliases,
                           implicit_id_in_shapes=implicit_id_in_shapes)

    return ir
Esempio n. 23
0
 def reduce_Expr_NOT_ILIKE_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op='NOT ILIKE',
                            right=kids[3].val)
Esempio n. 24
0
 def reduce_Expr_OR_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.OR,
                            right=kids[2].val)
Esempio n. 25
0
 def reduce_Expr_UNION_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val, op='UNION',
                            right=kids[2].val)
Esempio n. 26
0
 def reduce_Expr_IS_NOT_Expr(self, *kids):
     self.val = qlast.BinOp(left=kids[0].val,
                            op=ast.ops.IS_NOT,
                            right=kids[3].val)