Skip to main content

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;
21
22use crate::{IID, analyze::VariableAnnotations, concept};
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    /// &lt;instance&gt; isa(!) &lt;type&gt;
69    Isa { instance: ConstraintVertex, r#type: ConstraintVertex, exactness: ConstraintExactness },
70    /// &lt;owner&gt; has &lt;attribute&gt;
71    Has { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
72    /// &lt;relation&gt; links (&lt;role&gt;: &lt;player&gt;)
73    Links {
74        relation: ConstraintVertex,
75        player: ConstraintVertex,
76        role: ConstraintVertex,
77        exactness: ConstraintExactness,
78    },
79    /// &lt;subtype&gt; sub(!) &lt;supertype&gt;
80    Sub { subtype: ConstraintVertex, supertype: ConstraintVertex, exactness: ConstraintExactness },
81    /// &lt;owner&gt; owns &lt;attribute&gt;
82    Owns { owner: ConstraintVertex, attribute: ConstraintVertex, exactness: ConstraintExactness },
83    /// &lt;relation&gt; relates &lt;role&gt;
84    Relates { relation: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
85    /// &lt;player&gt; plays &lt;role&gt;
86    Plays { player: ConstraintVertex, role: ConstraintVertex, exactness: ConstraintExactness },
87    /// let &lt;assigned&gt; = name(&lt;arguments&gt;)
88    /// e.g. let $x, $y = my_function($a, $b);
89    FunctionCall { name: String, assigned: Vec<ConstraintVertex>, arguments: Vec<ConstraintVertex> },
90    /// let &lt;assigned&gt; = &lt;expression&gt;
91    /// e.g. let $x = $y + 5;
92    /// Here, arguments will be `&lsqb;$y&rsqb;`
93    Expression { text: String, assigned: ConstraintVertex, arguments: Vec<ConstraintVertex> },
94    /// &lt;lhs&gt; is &lt;rhs&gt;
95    /// $x is $y
96    Is { lhs: ConstraintVertex, rhs: ConstraintVertex },
97    /// &lt;concept&gt; iid &lt;iid&gt;
98    /// e.g. `$y iid 0x1f0005000000000000012f`
99    Iid { concept: ConstraintVertex, iid: IID },
100    /// &lt;lhs&gt; &lt;comparator&gt; &lt;rhs&gt;
101    /// e.g. `$x &lt; 5`
102    Comparison { lhs: ConstraintVertex, rhs: ConstraintVertex, comparator: Comparator },
103    /// &lt;kind&gt; &lt;type&gt;
104    /// e.g. `entity person`
105    Kind { kind: concept::Kind, r#type: ConstraintVertex },
106    /// &lt;type&gt; label &lt;label&gt;
107    /// e.g. `$t label person`
108    Label { r#type: ConstraintVertex, label: String },
109    /// &lt;attribute_type&gt; value &lt;value_type&gt;
110    /// e.g. $t value string
111    Value { attribute_type: ConstraintVertex, value_type: concept::ValueType },
112    /// { &lt;branches&lsqb;0&rsqb;&gt; } or { &lt;branches&lsqb;1&rsqb;&gt; } &lsqb;or ...&rsqb;
113    Or {
114        /// Index into <code>Pipeline.conjunctions</code>
115        branches: Vec<ConjunctionID>,
116    },
117    /// not { &lt;conjunction&gt; }
118    Not {
119        /// Index into <code>Pipeline.conjunctions</code>
120        conjunction: ConjunctionID,
121    },
122    /// try { &lt;conjunction&gt; }
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///
142/// The types inferred for <code>Variable</code>, <code>Label</code> and <code>NamedRole</code> vertices
143/// can be read from the <code>variable_annotations</code> field of the <code>Conjunction</code> it is in.
144#[derive(Debug, Clone, PartialEq)]
145pub enum ConstraintVertex {
146    Variable(Variable),
147    Label(concept::type_::Type),
148    Value(concept::Value),
149    NamedRole(NamedRole),
150}
151
152/// A <code>NamedRole</code> vertex is used in links & relates constraints, as multiple relations may have roles with the same name.
153#[derive(Debug, Clone)]
154pub struct NamedRole {
155    pub variable: Variable,
156    pub name: String,
157}
158
159impl PartialEq for NamedRole {
160    fn eq(&self, other: &Self) -> bool {
161        self.variable == other.variable // Names will be equal unless they belong to different pipelines
162    }
163}
164
165/// A representation of the comparator used in a comparison constraint.
166#[repr(C)]
167#[derive(Debug, Clone)]
168pub enum Comparator {
169    Equal,
170    NotEqual,
171    LessThan,
172    LessOrEqual,
173    Greater,
174    GreaterOrEqual,
175    Like,
176    Contains,
177}
178
179impl Comparator {
180    /// The symbol representing the comparator in TypeQL
181    pub fn symbol(&self) -> &'static str {
182        match self {
183            Comparator::Equal => "==",
184            Comparator::NotEqual => "!=",
185            Comparator::LessThan => "<",
186            Comparator::LessOrEqual => "<=",
187            Comparator::Greater => ">",
188            Comparator::GreaterOrEqual => ">=",
189            Comparator::Like => "Like",
190            Comparator::Contains => "Contains",
191        }
192    }
193}