typedb_driver/analyze/
conjunction.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20use std::{collections::HashMap, fmt};
21
22use crate::{analyze::VariableAnnotations, concept, IID};
23
24/// Holds the index of the conjunction in a <code>Pipeline</code>'s <code>conjunctions</code> field.
25/// Used as indirection in the representation of a pipeline.
26#[derive(Debug, Clone, Copy, PartialEq)]
27pub struct ConjunctionID(pub usize);
28
29/// A representation of the constraints involved in the query, and types inferred for each variable.
30#[derive(Debug, Clone)]
31pub struct Conjunction {
32    /// The <code>Constraint</code>s in the conjunction.
33    pub constraints: Vec<ConstraintWithSpan>,
34    /// The annotations of each variable in the conjunction.
35    pub variable_annotations: HashMap<Variable, VariableAnnotations>,
36}
37
38/// Tells apart exact variants of constraints from the ones allowing subtype-polymorphism.
39/// e.g. <code>isa!</code> would be represented as an <code>Constraint::Isa</code>
40/// with its exactness field <code>ConstraintExactness::Exact</code>.
41#[repr(C)]
42#[derive(Debug, Clone)]
43pub enum ConstraintExactness {
44    /// Indicates the constraint matches exactly the specified type - e.g. `isa!` or `sub!`
45    Exact,
46    /// Indicates the constraint matches the specified type and its subtypes - e.g. `isa!` or `sub!`
47    Subtypes,
48}
49
50/// The span of a constraint in the <code>source</code> of the <code>AnalyzedQuery</code>.
51#[derive(Debug, Clone)]
52pub struct ConstraintSpan {
53    /// The offset of the first character in the span
54    pub begin: usize,
55    /// The offset after the last character in the span
56    pub end: usize,
57}
58
59#[derive(Debug, Clone)]
60pub struct ConstraintWithSpan {
61    pub constraint: Constraint,
62    pub span: Option<ConstraintSpan>,
63}
64
65/// A representation of a TypeQL constraint.
66#[derive(Debug, Clone)]
67pub enum Constraint {
68    /// <instance> isa(!) <type>
69    Isa { instance: ConstraintVertex, r#type: ConstraintVertex, exactness: ConstraintExactness },
70    /// <owner> has <attribute>
71    Has { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
72    /// <relation> links (<role>: <player>)
73    Links {
74        relation: ConstraintVertex,
75        player: ConstraintVertex,
76        role: ConstraintVertex,
77        exactness: ConstraintExactness,
78    },
79    /// <subtype> sub(!) <supertype>
80    Sub { subtype: ConstraintVertex, supertype: ConstraintVertex, exactness: ConstraintExactness },
81    /// <owner> owns <attribute>
82    Owns { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
83    /// <relation> relates <role>
84    Relates { relation: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
85    /// <player> plays <role>
86    Plays { player: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
87    /// let <assigned> = name(<arguments>)
88    /// e.g. let $x, $y = my_function($a, $b);
89    FunctionCall { name: String, assigned: Vec<ConstraintVertex>, arguments: Vec<ConstraintVertex> },
90    /// let <assigned> = <expression>
91    /// e.g. let $x = $y + 5;
92    /// Here, arguments will be `[$y]`
93    Expression { text: String, assigned: ConstraintVertex, arguments: Vec<ConstraintVertex> },
94    /// <lhs> is <rhs>
95    /// $x is $y
96    Is { lhs: ConstraintVertex, rhs: ConstraintVertex },
97    /// <concept> iid <iid>
98    /// e.g. `$y iid 0x1f0005000000000000012f`
99    Iid { concept: ConstraintVertex, iid: IID },
100    /// <lhs> <comparator> <rhs>
101    /// e.g. `$x < 5`
102    Comparison { lhs: ConstraintVertex, rhs: ConstraintVertex, comparator: Comparator },
103    /// <kind> <type>
104    /// e.g. `entity person`
105    Kind { kind: concept::Kind, r#type: ConstraintVertex },
106    /// <type> label <label>
107    /// e.g. `$t label person`
108    Label { r#type: ConstraintVertex, label: String },
109    /// <attribute_type> value <value_type>
110    /// e.g. $t value string
111    Value { attribute_type: ConstraintVertex, value_type: concept::ValueType },
112    /// { <branches[0]> } or { <branches[1]> } [or ...]
113    Or {
114        /// Index into <code>Pipeline.conjunctions</code>
115        branches: Vec<ConjunctionID>,
116    },
117    /// not { <conjunction> }
118    Not {
119        /// Index into <code>Pipeline.conjunctions</code>
120        conjunction: ConjunctionID,
121    },
122    /// try { <conjunction> }
123    Try {
124        /// Index into <code>Pipeline.conjunctions</code>
125        conjunction: ConjunctionID,
126    },
127}
128
129/// Uniquely identifies a variable in a <code>Pipeline</code>pipeline.
130/// Its name (if any) can be retrieved from the <code>variable_names</code> field in <code>Pipeline</code>
131#[derive(Debug, Hash, Clone, Eq, PartialEq)]
132pub struct Variable(pub u32);
133
134/// The answer to a TypeDB query is a set of concepts which satisfy the <code>Constraints</code> in the query.
135/// A <code>ConstraintVertex</code> is either a variable, or some identifier of the concept.
136///
137/// * A <code>Variable</code> is a vertex the query must match and return.
138/// * A <code>Label</code> uniquely identifies a type
139/// * A <code>Value</code> represents a primitive value literal in TypeDB.
140/// * A <code>NamedRole</code> vertex is used in links & relates constraints, as multiple relations may have roles with the same name.
141/// The types inferred for <code>Variable</code>, <code>Label</code> and <code>NamedRole</code> vertices
142/// can be read from the <code>variable_annotations</code> field of the <code>Conjunction</code> it is in.
143#[derive(Debug, Clone, PartialEq)]
144pub enum ConstraintVertex {
145    Variable(Variable),
146    Label(concept::type_::Type),
147    Value(concept::Value),
148    NamedRole(NamedRole),
149}
150
151/// A <code>NamedRole</code> vertex is used in links & relates constraints, as multiple relations may have roles with the same name.
152#[derive(Debug, Clone)]
153pub struct NamedRole {
154    pub variable: Variable,
155    pub name: String,
156}
157
158impl PartialEq for NamedRole {
159    fn eq(&self, other: &Self) -> bool {
160        self.variable == other.variable // Names will be equal unless they belong to different pipelines
161    }
162}
163
164/// A representation of the comparator used in a comparison constraint.
165#[repr(C)]
166#[derive(Debug, Clone)]
167pub enum Comparator {
168    Equal,
169    NotEqual,
170    LessThan,
171    LessOrEqual,
172    Greater,
173    GreaterOrEqual,
174    Like,
175    Contains,
176}
177
178impl Comparator {
179    /// The symbol representing the comparator in TypeQL
180    pub fn symbol(&self) -> &'static str {
181        match self {
182            Comparator::Equal => "==",
183            Comparator::NotEqual => "!=",
184            Comparator::LessThan => "<",
185            Comparator::LessOrEqual => "<=",
186            Comparator::Greater => ">",
187            Comparator::GreaterOrEqual => ">=",
188            Comparator::Like => "Like",
189            Comparator::Contains => "Contains",
190        }
191    }
192}