Beispiel #1
0
def convert_any_all(node, state):
    if len(node.args) != 1 or node.keywords:
        raise ReizQLSyntaxError(
            f"Parameter mismatch for built-in function: {node.name!r}")

    check = compile_edgeql(*node.args, state)
    negated = isinstance(check, EdgeQLNot)
    if negated:
        check = check.value

    if isinstance(check, EdgeQLSelect) and check.filters:
        operator = EdgeQLComparisonOperator.EQUALS
    elif isinstance(check, EdgeQLSelect) and not check.filters:
        check = protected_name(check.name, prefix=True)
        operator = EdgeQLComparisonOperator.IDENTICAL
    else:
        raise ReizQLSyntaxError(
            "Unsupported operation passed into built-in function")

    if negated:
        operator = operator.negate()

    return EdgeQLFilter(
        EdgeQLCall(
            node.name.lower(),
            [EdgeQLFilter(EdgeQLFilterKey(state.pointer), check, operator)],
        ),
        EdgeQLPreparedQuery("True"),
    )
Beispiel #2
0
def generate_typechecked_query_item(query, base):
    rec_list = False
    if isinstance(query.key, EdgeQLCall) and isinstance(
            query.key.args[0], EdgeQLFilterKey):
        name = query.key.args[0].name
        rec_list = True
    elif isinstance(query.key, EdgeQLFilterKey):
        name = query.key.name
    else:
        raise ReizQLSyntaxError(
            f"Unknown matcher type for list expression: {type(query).__name__}"
        )

    key = EdgeQLAttribute(base, name)

    if rec_list:
        query.key.args[0] = key
        return query
    elif isinstance(query.value, EdgeQLPreparedQuery):
        query.key = key
        return query
    elif isinstance(query.value, EdgeQLSelect):
        model = protected_name(query.value.name, prefix=True)
        verifier = EdgeQLVerify(key, EdgeQLVerifyOperator.IS, model)
        if query.value.filters:
            return generate_typechecked_query(query.value.filters, verifier)
        else:
            return EdgeQLFilter(
                EdgeQLAttribute(base, query.key.name),
                model,
                EdgeQLComparisonOperator.IDENTICAL,
            )
    else:
        raise ReizQLSyntaxError("Unsupported syntax")
Beispiel #3
0
def convert_list(node, state):
    object_verifier = EdgeQLFilter(
        EdgeQLCall("count", [EdgeQLFilterKey(state.pointer)]), len(node.items))
    if len(node.items) == 0 or all(item is ReizQLIgnore
                                   for item in node.items):
        return object_verifier

    assignments = {}
    select_filters = None
    for index, item in enumerate(node.items):
        if item is ReizQLIgnore:
            continue
        elif not isinstance(item, ReizQLMatch):
            raise ReizQLSyntaxError(
                "A list may only contain matchers, not atoms")

        selection = EdgeQLSelect(
            EdgeQLFilterKey(state.pointer),
            ordered=EdgeQLProperty("index"),
            offset=index,
            limit=1,
        )
        filters = convert_match(item).filters

        # If there are no value queries, only type-check
        name = f"__item_{index}_{id(filters)}"
        if filters is None:
            assignments[name] = selection
            select_filters = merge_filters(
                select_filters,
                EdgeQLFilter(
                    EdgeQLName(name),
                    protected_name(item.name, prefix=True),
                    EdgeQLComparisonOperator.IDENTICAL,
                ),
            )
        else:
            assignments[name] = EdgeQLVerify(
                selection,
                EdgeQLVerifyOperator.IS,
                protected_name(item.name, prefix=True),
            )
            select_filters = merge_filters(
                select_filters,
                generate_typechecked_query(filters, name),
            )

    if assignments:
        with_block = EdgeQLWithBlock(assignments)
    else:
        with_block = None

    value_verifier = EdgeQLSelect(
        select_filters,
        with_block=with_block,
    )
    return EdgeQLFilterChain(
        object_verifier,
        value_verifier,
    )
Beispiel #4
0
 def parse_unary(self, node):
     if isinstance(node.op, ast.Not):
         return grammar.Not(self.parse(node.operand))
     elif isinstance(node.op, ast.Invert):
         ensure(isinstance(node.operand, ast.Name))
         return grammar.Ref(node.operand.id)
     else:
         raise ReizQLSyntaxError.from_node(node, "unknown unary operator")
Beispiel #5
0
def generate_typechecked_query(filters, base):
    base_query = None
    for query, operator in unpack_filters(filters):
        if isinstance(query, EdgeQLSelect):
            current_query = generate_typechecked_selection(query, base)
        elif isinstance(query, EdgeQLFilter):
            current_query = generate_typechecked_query_item(query, base)
        else:
            raise ReizQLSyntaxError("Unsupported syntax")

        base_query = merge_filters(base_query, current_query, operator)

    return base_query
Beispiel #6
0
    def get_ordered_parents(self):
        parents = self.parents + [self]
        enumeration_start = self.get_property("enumeration start depth")
        if enumeration_start is None:
            return parents

        for index, parent in enumerate(parents):
            if parent.depth == enumeration_start:
                break
        else:
            raise ReizQLSyntaxError(
                "compiler check failed: no enumeration start block found!"
            )
        return parents[index:]
Beispiel #7
0
    def parse_binop(self, node):
        if isinstance(node.op, ast.BitOr):
            operator = grammar.LogicOperator.OR
        elif isinstance(node.op, ast.BitAnd):
            operator = grammar.LogicOperator.AND
        else:
            raise ReizQLSyntaxError.from_node(
                node.op,
                f"Unknown logical operation: {type(node.op).__name__}")

        return grammar.LogicalOperation(
            left=self.parse(node.left),
            right=self.parse(node.right),
            operator=operator,
        )
Beispiel #8
0
def parse_query(source):
    if isinstance(source, bytes):
        source = source.decode()

    try:
        tree = ast.parse(source)
    except SyntaxError as exc:
        raise ReizQLSyntaxError(exc.args[0])

    ensure(len(tree.body) == 1)
    ensure(isinstance(tree.body[0], ast.Expr), tree.body[0])
    ensure(isinstance(tree.body[0].value, ast.Call), tree.body[0].value)

    parser = Parser(source)
    root_node = parser.parse(tree.body[0].value)

    ensure(isinstance(root_node, grammar.Match), tree.body[0])
    ensure(root_node.positional, tree.body[0])
    return root_node
Beispiel #9
0
 def parse(self, node):
     raise ReizQLSyntaxError.from_node(node, "Invalid syntax")
Beispiel #10
0
def ensure(condition, node=None, message="Invalid syntax"):
    if not condition:
        if node is None:
            raise ReizQLSyntaxError(message)
        else:
            raise ReizQLSyntaxError.from_node(node, message)
Beispiel #11
0
 def verify(self):
     for definition, (scope, _) in self.definitions.items():
         if scope.reference_counts[definition] < 1:
             raise ReizQLSyntaxError(f"unused reference: {definition!r}")
Beispiel #12
0
def compile_edgeql(obj, state):
    raise ReizQLSyntaxError(f"Unexpected query object: {obj!r}")
Beispiel #13
0
 def ensure(self, node, condition):
     if not condition:
         raise ReizQLSyntaxError(f"compiler check failed for: {node!r}")